0
0
Fork 0

Merge branch 'release/v0.1.0'

This commit is contained in:
windowsair 2020-02-05 18:59:05 +08:00
commit f45e017c65
40 changed files with 9008 additions and 258 deletions

1
.gitignore vendored
View File

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

27
.travis.yml Normal file
View File

@ -0,0 +1,27 @@
language: c
sudo: required
before_install:
- sudo apt install -y gcc git wget make libncurses-dev flex bison python python-serial
- wget https://dl.espressif.com/dl/xtensa-lx106-elf-linux64-1.22.0-100-ge567ec7-5.2.0.tar.gz
install:
- tar -xzf ./xtensa-lx106-elf-linux64-1.22.0-100-ge567ec7-5.2.0.tar.gz
- git clone --recursive https://github.com/espressif/ESP8266_RTOS_SDK.git
- python -m pip install --user -r ./ESP8266_RTOS_SDK/requirements.txt
before_script:
- export IDF_PATH=$PWD/ESP8266_RTOS_SDK
- export PATH="$PATH:$PWD/xtensa-lx106-elf/bin"
script:
- python ./idf.py fullclean
- python ./idf.py build
deploy:
provider: releases
api_key: ${GITHUB_TOKEN}
file:
- ./build/esp8266_dap.bin
skip_cleanup: true
on:
tags: true

View File

@ -1,6 +1,7 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
#set(COMPONENT_DIRS "${IDF_PATH}/components ${PROJECT_PATH}/components")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(tcp_server)
project(esp8266_dap)

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 windowsair
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

159
README.md
View File

@ -0,0 +1,159 @@
<p align="center"><img src="https://user-images.githubusercontent.com/17078589/73821108-300bda00-482e-11ea-89f6-011a50037a12.png"/></p>
<h1 align="center">Wireless ESP8266 DAP</h1>
[![Build Status](https://travis-ci.com/windowsair/wireless-esp8266-dap.svg?branch=master)](https://travis-ci.com/windowsair/wireless-esp8266-dap) master
[![Build Status](https://travis-ci.com/windowsair/wireless-esp8266-dap.svg?branch=develop)](https://travis-ci.com/windowsair/wireless-esp8266-dap) develop
[![](https://img.shields.io/badge/license-MIT-green.svg?style=flat-square)](https://github.com/windowsair/wireless-esp8266-dap/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg?style=flat-square)](https://github.com/windowsair/wireless-esp8266-dap/pulls) [![%e2%9d%a4](https://img.shields.io/badge/made%20with-%e2%9d%a4-ff69b4.svg?style=flat-square)](https://github.com/windowsair/wireless-esp8266-dap)
## Introduce
Wireless debugging with ***only one ESP8266*** !
Realized by USBIP and CMSIS-DAP protocol stack.
> 👉 5m distance, 100kb size firmware flash test:
<p align="center"><img src="https://user-images.githubusercontent.com/17078589/73829782-808b3380-483e-11ea-8389-1570bc4200af.gif"/></p>
## Feature
1. Debug Communication Mode
- [x] SWJ
- [x] JTAG
2. USB Communication Mode
- [x] USB-HID
- [ ] WCID & WinUSB
3. Debug Trace
- [ ] UART Serial Wire Output(SWO)
- [ ] SWO Streaming Trace
4. More..
- [x] Custom maximum debug clock(more than 10MHz)
- [ ] ...
## Link your board
1. WIFI
The default connected WIFI SSID is `DAP` , password `12345678`
You can change `WIFI_SSID` and ` WIFI_PASS` in [wifi_configuration.h](main/wifi_configuration.h)
2. Debugger
- SWD
| SWD | |
|----------------|--------|
| SWCLK | GPIO5 |
| SWDIO | GPIO4 |
| LED\_CONNECTED | GPIO2 |
| LED\_RUNNING | GPIO15 |
| TVCC | 3V3 |
| GND | GND |
- JTAG
| JTAG | |
|--------------------|---------|
| TCK | GPIO5 |
| TMS | GPIO4 |
| TDI | GPIO13 |
| TDO | GPIO12 |
| nTRST \(optional\) | GPIO0\* |
| nRESET | GPIO14 |
| LED\_CONNECTED | GPIO2 |
| LED\_RUNNING | GPIO15 |
| TVCC | 3V3 |
| GND | GND |
You can modify these pin definitions in [DAP_config.h](components/DAP/config/DAP_config.h)
> Tips: Try to avoid using `GPIO0`(working mode switch) and `GPIO16`(RTC)
## Build
1. Get ESP8266 RTOS Software Development Kit
See: [ESP8266_RTOS_SDK](https://github.com/espressif/ESP8266_RTOS_SDK "ESP8266_RTOS_SDK")
2. Build & Flash
Build with ESP-IDF build system.
More information can be found at the following link: [Build System](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html "Build System")
The following example shows a possible way to build on Windows:
```bash
# Build
python ./idf.py build
# Flash
python ./idf.py -p /dev/ttyS5 flash
```
> We also provided sample firmware quick evaluation. See [Releases](https://github.com/windowsair/wireless-esp8266-dap/releases)
## Usage
1. Get USBIP project
- Windows: [usbip-windows](https://github.com/george-hopkins/usbip-windows "usbip-windows") . Or you can find it already built here: https://github.com/barbalion/usbip-win-client
- Linux: Distributed as part of the kernel
2. Start esp8266 and connect it to the device to be debugged
3. Connect it with usbip:
```bash
.\usbip.exe -D -a <your-esp8266-ip-address> 1-1
```
If all goes well, you should see your device connected.
![image](https://user-images.githubusercontent.com/17078589/73833411-eb3f6d80-4844-11ea-8501-02a008f6119d.png)
![target](https://user-images.githubusercontent.com/17078589/73830040-eb3c6f00-483e-11ea-85ee-c40b68a836b2.png)
## Develop
> Credits to:
> - https://github.com/thevoidnn/esp8266-wifi-cmsis-dap for adapter firmware based on CMSIS-DAP v1.0
> - https://github.com/ARM-software/CMSIS_5 for CMSIS
In this repo you can find the complete implementation of the USB protocol stack including USB-HID, WCID, WinUSB. Although WinUSB-based mode currently does not work on USBIP :disappointed_relieved: . They are very easy and can help you quickly build your own DAP on other hardware platforms.
Currently using USB-HID for transmission is still slightly slower, If you have any ideas, welcome:
- [New issues](https://github.com/windowsair/wireless-esp8266-dap/issues)
- [New pull](https://github.com/windowsair/wireless-esp8266-dap/pulls)
### Issue
2-4
Due to the limitation of USB-HID (I'm not sure if this is a problem with USBIP or Windows), now each URB packet can only reach 255 bytes (About 1MBps bandwidth), which has not reached the upper limit of ESP8266 transmission bandwidth.
I now have an idea to construct a Man-in-the-middle between the two to forward traffic, thereby increasing the bandwidth of each transmission.
1-31
At present, the adaptation to WCID, WinUSB, etc. has all been completed. However, when transmitting data on the endpoint, we received an error message from USBIP. This is most likely a problem with the USBIP project itself.
Due to the completeness of the USBIP protocol document, we have not yet understood its role in the Bulk transmission process, which may also lead to errors in subsequent processes.
We will continue to try to make it work on USB HID. Once the USBIP problem is solved, we will immediately transfer it to work on WinUSB
## License
[MIT LICENSE](LICENSE)

View File

@ -0,0 +1,5 @@
set(COMPONENT_ADD_INCLUDEDIRS "config include $ENV{IDF_PATH}/components/esp8266/include/esp8266/ $ENV{IDF_PATH}//components/esp_ringbuf/include/")
set(COMPONENT_SRCS "./source/DAP.c ./source/DAP_vendor.c ./source/JTAG_DP.c ./source/SW_DP.c ./source/SWO.c ./source/uart_modify.c")
register_component()

View File

@ -0,0 +1,764 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 1. December 2017
* $Revision: V2.0.0
*
* Project: CMSIS-DAP Configuration
* Title: DAP_config.h CMSIS-DAP Configuration File (Template)
*
*---------------------------------------------------------------------------*/
#ifndef __DAP_CONFIG_H__
#define __DAP_CONFIG_H__
#include <stdint.h>
#include <string.h>
#include "cmsis_compiler.h"
#include "gpio.h"
#include "gpio_struct.h"
#include "timer_struct.h"
#include "esp8266/pin_mux_register.h"
//**************************************************************************************************
/**
\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information
\ingroup DAP_ConfigIO_gr
@{
Provides definitions about the hardware and configuration of the Debug Unit.
This information includes:
- Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit.
- Debug Unit Identification strings (Vendor, Product, Serial Number).
- Debug Unit communication packet size.
- Debug Access Port supported modes and settings (JTAG/SWD and SWO).
- Optional information about a connected Target Device (for Evaluation Boards).
*/
//#ifdef _RTE_
//#include "RTE_Components.h"
//#include CMSIS_device_header
//#else
//#include "device.h" // Debug Unit Cortex-M Processor Header File
//#endif
/// Processor Clock of the Cortex-M MCU used in the Debug Unit.
/// This value is used to calculate the SWD/JTAG clock speed.
#define CPU_CLOCK 160000000 ///< Specifies the CPU Clock in Hz.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz
// This value is used to replace the largest 10MHZ speed clock in Keil
#define MAX_USER_CLOCK 10000000 ///< Specifies the max Debug Clock in Hz.
/// Number of processor cycles for I/O Port write operations.
/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O
/// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors
/// require 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses
/// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be
/// required.
#define IO_PORT_WRITE_CYCLES 2U ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0.
/// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port.
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
#define DAP_SWD 1 ///< SWD Mode: 1 = available, 0 = not available.
/// Indicate that JTAG communication mode is available at the Debug Port.
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available.
/// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port.
/// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255.
#define DAP_JTAG_DEV_CNT 8U ///< Maximum number of JTAG devices on scan chain.
/// Default communication mode on the Debug Access Port.
/// Used for the command \ref DAP_Connect when Port Default mode is selected.
#define DAP_DEFAULT_PORT 1U ///< Default JTAG/SWJ Port Mode: 1 = SWD, 2 = JTAG.
/// Default communication speed on the Debug Access Port for SWD and JTAG mode.
/// Used to initialize the default SWD/JTAG clock frequency.
/// The command \ref DAP_SWJ_Clock can be used to overwrite this default setting.
#define DAP_DEFAULT_SWJ_CLOCK 1000000U ///< Default SWD/JTAG clock frequency in Hz.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<1MHz
/// Maximum Package Size for Command and Response data.
/// This configuration settings is used to optimize the communication performance with the
/// debugger and depends on the USB peripheral. Typical vales are 64 for Full-speed USB HID or WinUSB,
/// 1024 for High-speed USB HID and 512 for High-speed USB WinUSB.
#define DAP_PACKET_SIZE 255U ///< Specifies Packet Size in bytes.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 512 for High-speed USB WinUSB.
/// Maximum Package Buffers for Command and Response data.
/// This configuration settings is used to optimize the communication performance with the
/// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the
/// setting can be reduced (valid range is 1 .. 255).
#define DAP_PACKET_COUNT 20 ///< Specifies number of packets buffered.
/// Indicate that UART Serial Wire Output (SWO) trace is available.
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
#define SWO_UART 0 ///< SWO UART: 1 = available, 0 = not available.
/// Maximum SWO UART Baudrate.
#define SWO_UART_MAX_BAUDRATE (115200U * 40U) ///< SWO UART Maximum Baudrate in Hz.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz
//// TODO: uncertain value
/// Indicate that Manchester Serial Wire Output (SWO) trace is available.
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available.
/// SWO Trace Buffer Size.
#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n).
/// SWO Streaming Trace.
#define SWO_STREAM 0 ///< SWO Streaming Trace: 1 = available, 0 = not available.
/// Clock frequency of the Test Domain Timer. Timer value is returned with \ref TIMESTAMP_GET.
#define TIMESTAMP_CLOCK 5000000U ///< Timestamp clock in Hz (0 = timestamps not supported).
// <<<<<<<<<<<<<<<<<<<<<5MHz
/// Debug Unit is connected to fixed Target Device.
/// The Debug Unit may be part of an evaluation board and always connected to a fixed
/// known device. In this case a Device Vendor and Device Name string is stored which
/// may be used by the debugger or IDE to configure device parameters.
#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown;
#if TARGET_DEVICE_FIXED
#define TARGET_DEVICE_VENDOR "ARM" ///< String indicating the Silicon Vendor
#define TARGET_DEVICE_NAME "Cortex-M4" ///< String indicating the Target Device
#endif
/**
* @brief Get Vendor ID string.
*
* @param str Pointer to buffer to store the string.
* @return String length.
*/
__STATIC_INLINE uint8_t DAP_GetVendorString(char *str)
{
////TODO: fill this
// In fact, Keil can get the corresponding information through USB
// without filling in this information.
// (void)str;
strcpy(str, "windowsair");
return (sizeof("windowsair"));
}
/**
* @brief Get Product ID string.
*
* @param str Pointer to buffer to store the string.
* @return String length.
*/
__STATIC_INLINE uint8_t DAP_GetProductString(char *str)
{
//(void)str;
strcpy(str, "CMSIS-DAP v2");
return (sizeof("CMSIS-DAP v2"));
}
/**
* @brief Get Serial Number string.
*
* @param str Pointer to buffer to store the string.
* @return String length.
*/
__STATIC_INLINE uint8_t DAP_GetSerNumString(char *str)
{
strcpy(str, "1234");
return (sizeof("1234"));
}
///@}
// Modify your pins here
// ATTENTION: DO NOT USE RTC GPIO16
#define PIN_SWDIO 4
#define PIN_SWCLK 5
#define PIN_TDO 13
#define PIN_TDI 12
#define PIN_nTRST 0 // optional
#define PIN_nRESET 14
// LED_BUILTIN
#define PIN_LED_CONNECTED 2
// LED_BUILTIN
#define PIN_LED_RUNNING 15
//**************************************************************************************************
/**
\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access
\ingroup DAP_ConfigIO_gr
@{
Standard I/O Pins of the CMSIS-DAP Hardware Debug Port support standard JTAG mode
and Serial Wire Debug (SWD) mode. In SWD mode only 2 pins are required to implement the debug
interface of a device. The following I/O Pins are provided:
JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode
---------------------------- | -------------------- | ---------------------------------------------
TCK: Test Clock | SWCLK: Clock | Output Push/Pull
TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data)
TDI: Test Data Input | | Output Push/Pull
TDO: Test Data Output | | Input
nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor
nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor
DAP Hardware I/O Pin Access Functions
-------------------------------------
The various I/O Pins are accessed by functions that implement the Read, Write, Set, or Clear to
these I/O Pins.
For the SWDIO I/O Pin there are additional functions that are called in SWD I/O mode only.
This functions are provided to achieve faster I/O that is possible with some advanced GPIO
peripherals that can independently write/read a single I/O pin without affecting any other pins
of the same I/O port. The following SWDIO I/O Pin functions are provided:
- \ref PIN_SWDIO_OUT_ENABLE to enable the output mode from the DAP hardware.
- \ref PIN_SWDIO_OUT_DISABLE to enable the input mode to the DAP hardware.
- \ref PIN_SWDIO_IN to read from the SWDIO I/O pin with utmost possible speed.
- \ref PIN_SWDIO_OUT to write to the SWDIO I/O pin with utmost possible speed.
*/
/**
* @brief Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET.
* Configures the DAP Hardware I/O pins for JTAG mode:
* - TCK, TMS, TDI, nTRST, nRESET to ***output*** mode and set to high level.
* - TDO to ***input*** mode.
*
*/
__STATIC_INLINE void PORT_JTAG_SETUP(void)
{
gpio_pin_reg_t pin_reg;
// gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT);
// gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT);
GPIO.enable_w1ts |= (0x1 << PIN_SWCLK);
GPIO.pin[PIN_SWCLK].driver = 0;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWCLK));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWCLK), pin_reg.val);
GPIO.enable_w1ts |= (0x1 << PIN_SWDIO);
GPIO.pin[PIN_SWDIO].driver = 0;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWDIO));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWDIO), pin_reg.val);
// gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
GPIO.enable_w1tc |= (0x1 << PIN_TDO);
GPIO.pin[PIN_TDO].driver = 0;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDO));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDO), pin_reg.val);
// gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT);
GPIO.enable_w1ts |= (0x1 << PIN_TDI);
GPIO.pin[PIN_TDI].driver = 0;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDI));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDI), pin_reg.val);
// gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD);
// gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD);
GPIO.enable_w1tc |= (0x1 << PIN_nTRST);
GPIO.pin[PIN_nTRST].driver = 1;
GPIO.enable_w1tc |= (0x1 << PIN_nRESET);
GPIO.pin[PIN_nRESET].driver = 1;
// gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY);
// gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY);
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nTRST));
pin_reg.pullup = 1;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_nTRST), pin_reg.val);
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nRESET));
pin_reg.pullup = 1;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_nRESET), pin_reg.val);
}
/**
* @brief Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
* Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode:
* - SWCLK, SWDIO, nRESET to output mode and set to default high level.
* - TDI, nTRST to HighZ mode (pins are unused in SWD mode).
*
*/
__STATIC_INLINE void PORT_SWD_SETUP(void)
{
gpio_pin_reg_t pin_reg;
// gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT);
// gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT);
GPIO.enable_w1ts |= (0x1 << PIN_SWCLK);
GPIO.pin[PIN_SWCLK].driver = 0;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWCLK));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWCLK), pin_reg.val);
GPIO.enable_w1ts |= (0x1 << PIN_SWDIO);
GPIO.pin[PIN_SWDIO].driver = 0;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWDIO));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWDIO), pin_reg.val);
// gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
GPIO.enable_w1tc |= (0x1 << PIN_TDO);
GPIO.pin[PIN_TDO].driver = 0;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDO));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDO), pin_reg.val);
// gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT);
GPIO.enable_w1ts |= (0x1 << PIN_TDI);
GPIO.pin[PIN_TDI].driver = 0;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDI));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDI), pin_reg.val);
// gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD);
// gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD);
GPIO.enable_w1tc |= (0x1 << PIN_nTRST);
GPIO.pin[PIN_nTRST].driver = 1;
GPIO.enable_w1tc |= (0x1 << PIN_nRESET);
GPIO.pin[PIN_nRESET].driver = 1;
// gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY);
// gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY);
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nTRST));
pin_reg.pullup = 1;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_nTRST), pin_reg.val);
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nRESET));
pin_reg.pullup = 1;
WRITE_PERI_REG(GPIO_PIN_REG(PIN_nRESET), pin_reg.val);
}
/**
* @brief Disable JTAG/SWD I/O Pins.
* Disables the DAP Hardware I/O pins which configures:
* - TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
*
*/
__STATIC_INLINE void PORT_OFF(void)
{
// Will be called when the DAP disconnected
// gpio_set_direction(PIN_SWCLK, GPIO_MODE_DEF_DISABLE);
// gpio_set_direction(PIN_SWDIO, GPIO_MODE_DEF_DISABLE);
// gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_DISABLE);
// gpio_set_direction(PIN_TDI, GPIO_MODE_DEF_DISABLE);
// gpio_set_direction(PIN_nTRST, GPIO_MODE_DEF_DISABLE);
// gpio_set_direction(PIN_nRESET, GPIO_MODE_DEF_DISABLE);
GPIO.pin[PIN_SWCLK].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_SWCLK);
GPIO.pin[PIN_SWDIO].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_SWDIO);
GPIO.pin[PIN_TDO].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_TDO);
GPIO.pin[PIN_TDI].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_TDI);
GPIO.pin[PIN_nTRST].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_nTRST);
GPIO.pin[PIN_nRESET].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_nRESET);
}
// SWCLK/TCK I/O pin -------------------------------------
/**
* @brief SWCLK/TCK I/O pin: Get Input.
*
* @return Current status of the SWCLK/TCK DAP hardware I/O pin.
*/
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN(void)
{
////TODO: can we set to 0?
return 0;
}
/**
* @brief SWCLK/TCK I/O pin: Set Output to High.
*
* Set the SWCLK/TCK DAP hardware I/O pin to high level.
*/
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET(void)
{
GPIO.out_w1ts |= (0x1 << PIN_SWCLK);
}
/**
* @brief SWCLK/TCK I/O pin: Set Output to Low.
*
* Set the SWCLK/TCK DAP hardware I/O pin to low level.
*/
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void)
{
GPIO.out_w1tc |= (0x1 << PIN_SWCLK);
}
// SWDIO/TMS Pin I/O --------------------------------------
/**
* @brief SWDIO/TMS I/O pin: Get Input.
*
* @return Current status of the SWDIO/TMS DAP hardware I/O pin.
*/
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void)
{
return ((GPIO.in >> PIN_SWDIO) & 0x1) ? 1 : 0;
}
/**
* @brief SWDIO/TMS I/O pin: Set Output to High.
*
* Set the SWDIO/TMS DAP hardware I/O pin to high level.
*/
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void)
{
GPIO.out_w1ts |= (0x1 << PIN_SWDIO);
}
/**
* @brief SWDIO/TMS I/O pin: Set Output to Low.
*
* Set the SWDIO/TMS DAP hardware I/O pin to low level.
*/
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void)
{
GPIO.out_w1tc |= (0x1 << PIN_SWDIO);
}
/**
* @brief SWDIO I/O pin: Get Input (used in SWD mode only).
*
* @return Current status of the SWDIO DAP hardware I/O pin.
*/
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN(void)
{
return ((GPIO.in >> PIN_SWDIO) & 0x1) ? 1 : 0;
}
/**
* @brief SWDIO I/O pin: Set Output (used in SWD mode only).
*
* @param bit Output value for the SWDIO DAP hardware I/O pin.
*
*/
__STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit)
{
/**
* Important: Use only one bit (bit0) of param!
* Sometimes the func "SWD_TransferFunction" of SW_DP.c will
* issue "2" as param instead of "0". Zach Lee
*/
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_SWDIO);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_SWDIO);
}
}
/**
* @brief SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
* Configure the SWDIO DAP hardware I/O pin to output mode. This function is
* called prior \ref PIN_SWDIO_OUT function calls.
*/
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void)
{
// Need fast response
// set \ref gpio_set_direction -> OUTPUT
GPIO.enable_w1ts |= (0x1 << PIN_SWDIO);
GPIO.pin[PIN_SWDIO].driver = 0;
}
/**
* @brief SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
* Configure the SWDIO DAP hardware I/O pin to input mode. This function is
* called prior \ref PIN_SWDIO_IN function calls.
*/
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void)
{
// Need fast response
// set \ref gpio_set_dircetion -> INPUT
// esp8266 input is always connected
GPIO.enable_w1tc |= (0x1 << PIN_SWDIO);
GPIO.pin[PIN_SWDIO].driver = 0;
}
// TDI Pin I/O ---------------------------------------------
/**
* @brief TDI I/O pin: Get Input.
*
* @return Current status of the TDI DAP hardware I/O pin.
*/
__STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void)
{
return ((GPIO.in >> PIN_TDI) & 0x1) ? 1 : 0;
}
/**
* @brief TDI I/O pin: Set Output.
*
* @param bit Output value for the TDI DAP hardware I/O pin.
*
*/
__STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit)
{
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_TDI);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_TDI);
}
}
// TDO Pin I/O ---------------------------------------------
/**
* @brief TDO I/O pin: Get Input.
*
* @return Current status of the TDO DAP hardware I/O pin.
*/
__STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void)
{
return ((GPIO.in >> PIN_TDO) & 0x1) ? 1 : 0;
}
// nTRST Pin I/O -------------------------------------------
/**
* @brief nTRST I/O pin: Get Input.
*
* @return Current status of the nTRST DAP hardware I/O pin.
*/
__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void)
{
return 0; // not available
}
/**
* @brief nTRST I/O pin: Set Output.
*
* @param bit JTAG TRST Test Reset pin status:
* - 0: issue a JTAG TRST Test Reset.
- 1: release JTAG TRST Test Reset.
*/
__STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit)
{
// ////TODO: What does this mean? ? ?
// if ((bit & 1U) == 1)
// {
// //set bit
// GPIO.out_w1ts |= (0x1 << PIN_nTRST);
// }
// else
// {
// //reset bit
// GPIO.out_w1tc |= (0x1 << PIN_nTRST);
// }
; // not available
}
// nRESET Pin I/O------------------------------------------
/**
* @brief nRESET I/O pin: Get Input.
*
* @return Current status of the nRESET DAP hardware I/O pin.
*/
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void)
{
return ((GPIO.in >> PIN_nRESET) & 0x1) ? 1 : 0;
}
/**
* @brief nRESET I/O pin: Set Output.
*
* @param bit target device hardware reset pin status:
* - 0: issue a device hardware reset.
* - 1: release device hardware reset.
*/
__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit)
{
////TODO: What does this mean? ? ?
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_nRESET);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_nRESET);
}
}
///@}
//**************************************************************************************************
/**
\defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs
\ingroup DAP_ConfigIO_gr
@{
CMSIS-DAP Hardware may provide LEDs that indicate the status of the CMSIS-DAP Debug Unit.
It is recommended to provide the following LEDs for status indication:
- Connect LED: is active when the DAP hardware is connected to a debugger.
- Running LED: is active when the debugger has put the target device into running state.
*/
/** Debug Unit: Set status of Connected LED.
\param bit status of the Connect LED.
- 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit.
- 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
*/
/**
* @brief Debug Unit: Set status of Connected LED.
*
* @param bit status of the Connect LED.
* - 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit.
* - 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
*/
__STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit)
{
if (bit)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_LED_CONNECTED);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_LED_CONNECTED);
}
}
/**
* @brief Debug Unit: Set status Target Running LED.
*
* @param bit status of the Target Running LED.
* - 1: Target Running LED ON: program execution in target started.
* - 0: Target Running LED OFF: program execution in target stopped.
*/
__STATIC_INLINE void LED_RUNNING_OUT(uint32_t bit)
{
if (bit)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_LED_RUNNING);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_LED_RUNNING);
}
}
///@}
//**************************************************************************************************
/**
\defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp
\ingroup DAP_ConfigIO_gr
@{
Access function for Test Domain Timer.
The value of the Test Domain Timer in the Debug Unit is returned by the function \ref TIMESTAMP_GET. By
default, the DWT timer is used. The frequency of this timer is configured with \ref TIMESTAMP_CLOCK.
*/
/**
* @brief Get timestamp of Test Domain Timer.
*
* @return Current timestamp value.
*/
__STATIC_INLINE uint32_t TIMESTAMP_GET(void)
{
// FRC1 is a 23-bit countdown timer
return (0x7FFFFF - (frc1.count.data));
}
///@}
//**************************************************************************************************
/**
\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization
\ingroup DAP_ConfigIO_gr
@{
CMSIS-DAP Hardware I/O and LED Pins are initialized with the function \ref DAP_SETUP.
*/
/** Setup of the Debug Unit I/O pins and LEDs (called when Debug Unit is initialized).
This function performs the initialization of the CMSIS-DAP Hardware I/O Pins and the
Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled and set:
- I/O clock system enabled.
- all I/O pins: input buffer enabled, output pins are set to HighZ mode.
- for nTRST, nRESET a weak pull-up (if available) is enabled.
- LED output pins are enabled and LEDs are turned off.
*/
__STATIC_INLINE void DAP_SETUP(void)
{
// This function maybe unnecessary...
gpio_set_direction(PIN_SWCLK, GPIO_MODE_DEF_INPUT);
gpio_set_direction(PIN_SWDIO, GPIO_MODE_DEF_INPUT); //
gpio_set_direction(PIN_nRESET, GPIO_MODE_DEF_INPUT); //
gpio_set_direction(PIN_TDI, GPIO_MODE_DEF_INPUT);
gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
// Configure: LED as output (turned off)
gpio_set_direction(PIN_LED_CONNECTED, GPIO_MODE_DEF_OUTPUT);
LED_CONNECTED_OUT(0);
gpio_set_direction(PIN_LED_RUNNING, GPIO_MODE_DEF_OUTPUT);
LED_RUNNING_OUT(0);
}
/** Reset Target Device with custom specific I/O pin or command sequence.
This function allows the optional implementation of a device specific reset sequence.
It is called when the command \ref DAP_ResetTarget and is for example required
when a device needs a time-critical unlock sequence that enables the debug port.
\return 0 = no device specific reset sequence is implemented.\n
1 = a device specific reset sequence is implemented.
*/
__STATIC_INLINE uint8_t RESET_TARGET(void)
{
return (0U); // not available
}
///@}
#endif /* __DAP_CONFIG_H__ */

View File

@ -0,0 +1,330 @@
/*
* Copyright (c) 2013-2019 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 26. November 2019
* $Revision: V2.0.0
*
* Project: CMSIS-DAP Include
* Title: DAP.h Definitions
*
*---------------------------------------------------------------------------*/
#ifndef __DAP_H__
#define __DAP_H__
// DAP Firmware Version
#ifdef DAP_FW_V1
#define DAP_FW_VER "1.2.0"
#else
#define DAP_FW_VER "2.0.0"
#endif
// DAP Command IDs
#define ID_DAP_Info 0x00U
#define ID_DAP_HostStatus 0x01U
#define ID_DAP_Connect 0x02U
#define ID_DAP_Disconnect 0x03U
#define ID_DAP_TransferConfigure 0x04U
#define ID_DAP_Transfer 0x05U
#define ID_DAP_TransferBlock 0x06U
#define ID_DAP_TransferAbort 0x07U
#define ID_DAP_WriteABORT 0x08U
#define ID_DAP_Delay 0x09U
#define ID_DAP_ResetTarget 0x0AU
#define ID_DAP_SWJ_Pins 0x10U
#define ID_DAP_SWJ_Clock 0x11U
#define ID_DAP_SWJ_Sequence 0x12U
#define ID_DAP_SWD_Configure 0x13U
#define ID_DAP_SWD_Sequence 0x1DU
#define ID_DAP_JTAG_Sequence 0x14U
#define ID_DAP_JTAG_Configure 0x15U
#define ID_DAP_JTAG_IDCODE 0x16U
#define ID_DAP_SWO_Transport 0x17U
#define ID_DAP_SWO_Mode 0x18U
#define ID_DAP_SWO_Baudrate 0x19U
#define ID_DAP_SWO_Control 0x1AU
#define ID_DAP_SWO_Status 0x1BU
#define ID_DAP_SWO_ExtendedStatus 0x1EU
#define ID_DAP_SWO_Data 0x1CU
#define ID_DAP_QueueCommands 0x7EU
#define ID_DAP_ExecuteCommands 0x7FU
// DAP Vendor Command IDs
#define ID_DAP_Vendor0 0x80U
#define ID_DAP_Vendor1 0x81U
#define ID_DAP_Vendor2 0x82U
#define ID_DAP_Vendor3 0x83U
#define ID_DAP_Vendor4 0x84U
#define ID_DAP_Vendor5 0x85U
#define ID_DAP_Vendor6 0x86U
#define ID_DAP_Vendor7 0x87U
#define ID_DAP_Vendor8 0x88U
#define ID_DAP_Vendor9 0x89U
#define ID_DAP_Vendor10 0x8AU
#define ID_DAP_Vendor11 0x8BU
#define ID_DAP_Vendor12 0x8CU
#define ID_DAP_Vendor13 0x8DU
#define ID_DAP_Vendor14 0x8EU
#define ID_DAP_Vendor15 0x8FU
#define ID_DAP_Vendor16 0x90U
#define ID_DAP_Vendor17 0x91U
#define ID_DAP_Vendor18 0x92U
#define ID_DAP_Vendor19 0x93U
#define ID_DAP_Vendor20 0x94U
#define ID_DAP_Vendor21 0x95U
#define ID_DAP_Vendor22 0x96U
#define ID_DAP_Vendor23 0x97U
#define ID_DAP_Vendor24 0x98U
#define ID_DAP_Vendor25 0x99U
#define ID_DAP_Vendor26 0x9AU
#define ID_DAP_Vendor27 0x9BU
#define ID_DAP_Vendor28 0x9CU
#define ID_DAP_Vendor29 0x9DU
#define ID_DAP_Vendor30 0x9EU
#define ID_DAP_Vendor31 0x9FU
#define ID_DAP_Invalid 0xFFU
// DAP Status Code
#define DAP_OK 0U
#define DAP_ERROR 0xFFU
// DAP ID
#define DAP_ID_VENDOR 1U
#define DAP_ID_PRODUCT 2U
#define DAP_ID_SER_NUM 3U
#define DAP_ID_FW_VER 4U
#define DAP_ID_DEVICE_VENDOR 5U
#define DAP_ID_DEVICE_NAME 6U
#define DAP_ID_CAPABILITIES 0xF0U
#define DAP_ID_TIMESTAMP_CLOCK 0xF1U
#define DAP_ID_SWO_BUFFER_SIZE 0xFDU
#define DAP_ID_PACKET_COUNT 0xFEU
#define DAP_ID_PACKET_SIZE 0xFFU
// DAP Host Status
#define DAP_DEBUGGER_CONNECTED 0U
#define DAP_TARGET_RUNNING 1U
// DAP Port
#define DAP_PORT_AUTODETECT 0U // Autodetect Port
#define DAP_PORT_DISABLED 0U // Port Disabled (I/O pins in High-Z)
#define DAP_PORT_SWD 1U // SWD Port (SWCLK, SWDIO) + nRESET
#define DAP_PORT_JTAG 2U // JTAG Port (TCK, TMS, TDI, TDO, nTRST) + nRESET
// DAP SWJ Pins
#define DAP_SWJ_SWCLK_TCK 0 // SWCLK/TCK
#define DAP_SWJ_SWDIO_TMS 1 // SWDIO/TMS
#define DAP_SWJ_TDI 2 // TDI
#define DAP_SWJ_TDO 3 // TDO
#define DAP_SWJ_nTRST 5 // nTRST
#define DAP_SWJ_nRESET 7 // nRESET
// DAP Transfer Request
#define DAP_TRANSFER_APnDP (1U<<0)
#define DAP_TRANSFER_RnW (1U<<1)
#define DAP_TRANSFER_A2 (1U<<2)
#define DAP_TRANSFER_A3 (1U<<3)
#define DAP_TRANSFER_MATCH_VALUE (1U<<4)
#define DAP_TRANSFER_MATCH_MASK (1U<<5)
#define DAP_TRANSFER_TIMESTAMP (1U<<7)
// DAP Transfer Response
#define DAP_TRANSFER_OK (1U<<0)
#define DAP_TRANSFER_WAIT (1U<<1)
#define DAP_TRANSFER_FAULT (1U<<2)
#define DAP_TRANSFER_ERROR (1U<<3)
#define DAP_TRANSFER_MISMATCH (1U<<4)
// DAP SWO Trace Mode
#define DAP_SWO_OFF 0U
#define DAP_SWO_UART 1U
#define DAP_SWO_MANCHESTER 2U
// DAP SWO Trace Status
#define DAP_SWO_CAPTURE_ACTIVE (1U<<0)
#define DAP_SWO_CAPTURE_PAUSED (1U<<1)
#define DAP_SWO_STREAM_ERROR (1U<<6)
#define DAP_SWO_BUFFER_OVERRUN (1U<<7)
// Debug Port Register Addresses
#define DP_IDCODE 0x00U // IDCODE Register (SW Read only)
#define DP_ABORT 0x00U // Abort Register (SW Write only)
#define DP_CTRL_STAT 0x04U // Control & Status
#define DP_WCR 0x04U // Wire Control Register (SW Only)
#define DP_SELECT 0x08U // Select Register (JTAG R/W & SW W)
#define DP_RESEND 0x08U // Resend (SW Read Only)
#define DP_RDBUFF 0x0CU // Read Buffer (Read Only)
// JTAG IR Codes
#define JTAG_ABORT 0x08U
#define JTAG_DPACC 0x0AU
#define JTAG_APACC 0x0BU
#define JTAG_IDCODE 0x0EU
#define JTAG_BYPASS 0x0FU
// JTAG Sequence Info
#define JTAG_SEQUENCE_TCK 0x3FU // TCK count
#define JTAG_SEQUENCE_TMS 0x40U // TMS value
#define JTAG_SEQUENCE_TDO 0x80U // TDO capture
// SWD Sequence Info
#define SWD_SEQUENCE_CLK 0x3FU // SWCLK count
#define SWD_SEQUENCE_DIN 0x80U // SWDIO capture
#include <stddef.h>
#include <stdint.h>
#include "cmsis_compiler.h"
// DAP Data structure
typedef struct {
uint8_t debug_port; // Debug Port
uint8_t fast_clock; // Fast Clock Flag
uint8_t padding[2];
uint32_t clock_delay; // Clock Delay
uint32_t timestamp; // Last captured Timestamp
struct { // Transfer Configuration
uint8_t idle_cycles; // Idle cycles after transfer
uint8_t padding[3];
uint16_t retry_count; // Number of retries after WAIT response
uint16_t match_retry; // Number of retries if read value does not match
uint32_t match_mask; // Match Mask
} transfer;
#if (DAP_SWD != 0)
struct { // SWD Configuration
uint8_t turnaround; // Turnaround period
uint8_t data_phase; // Always generate Data Phase
} swd_conf;
#endif
#if (DAP_JTAG != 0)
struct { // JTAG Device Chain
uint8_t count; // Number of devices
uint8_t index; // Device index (device at TDO has index 0)
#if (DAP_JTAG_DEV_CNT != 0)
uint8_t ir_length[DAP_JTAG_DEV_CNT]; // IR Length in bits
uint16_t ir_before[DAP_JTAG_DEV_CNT]; // Bits before IR
uint16_t ir_after [DAP_JTAG_DEV_CNT]; // Bits after IR
#endif
} jtag_dev;
#endif
} DAP_Data_t;
extern DAP_Data_t DAP_Data; // DAP Data
extern volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag
#ifdef __cplusplus
extern "C"
{
#endif
// Functions
extern void SWJ_Sequence (uint32_t count, const uint8_t *data);
extern void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi);
extern void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo);
extern void JTAG_IR (uint32_t ir);
extern uint32_t JTAG_ReadIDCode (void);
extern void JTAG_WriteAbort (uint32_t data);
extern uint8_t JTAG_Transfer (uint32_t request, uint32_t *data);
extern uint8_t SWD_Transfer (uint32_t request, uint32_t *data);
extern void Delayms (uint32_t delay);
extern uint32_t SWO_Transport (const uint8_t *request, uint8_t *response);
extern uint32_t SWO_Mode (const uint8_t *request, uint8_t *response);
extern uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response);
extern uint32_t SWO_Control (const uint8_t *request, uint8_t *response);
extern uint32_t SWO_Status (uint8_t *response);
extern uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response);
extern uint32_t SWO_Data (const uint8_t *request, uint8_t *response);
extern void SWO_QueueTransfer (uint8_t *buf, uint32_t num);
extern void SWO_AbortTransfer (void);
extern void SWO_TransferComplete (void);
extern uint32_t UART_SWO_Mode (uint32_t enable);
extern uint32_t UART_SWO_Baudrate (uint32_t baudrate);
extern uint32_t UART_SWO_Control (uint32_t active);
extern void UART_SWO_Capture (uint8_t *buf, uint32_t num);
extern uint32_t UART_SWO_GetCount (void);
extern uint32_t Manchester_SWO_Mode (uint32_t enable);
extern uint32_t Manchester_SWO_Baudrate (uint32_t baudrate);
extern uint32_t Manchester_SWO_Control (uint32_t active);
extern void Manchester_SWO_Capture (uint8_t *buf, uint32_t num);
extern uint32_t Manchester_SWO_GetCount (void);
extern uint32_t DAP_ProcessVendorCommand (const uint8_t *request, uint8_t *response);
extern uint32_t DAP_ProcessCommand (const uint8_t *request, uint8_t *response);
extern uint32_t DAP_ExecuteCommand (const uint8_t *request, uint8_t *response);
extern void DAP_Setup (void);
// Configurable delay for clock generation
#ifndef DELAY_SLOW_CYCLES
#define DELAY_SLOW_CYCLES 3U // Number of cycles for one iteration
#endif
#define USE_ASSEMBLY 1
#if (USE_ASSEMBLY == 0)
__STATIC_FORCEINLINE void PIN_DELAY_SLOW(uint32_t delay)
{
uint32_t count = delay;
while (--count)
;
}
#else
__STATIC_FORCEINLINE void PIN_DELAY_SLOW(uint32_t delay)
{
__asm__ volatile(
"l_PINDELAYSLOW%=:"
"ADDI.N %[time], %[time], -1;"
"BNEZ %[time], l_PINDELAYSLOW%=;"
: [time] "+r"(delay));
}
#endif
// Fixed delay for fast clock generation
#ifndef DELAY_FAST_CYCLES
#define DELAY_FAST_CYCLES 0U // Number of cycles: 0..3
#endif
__STATIC_FORCEINLINE void PIN_DELAY_FAST (void) {
#if (DELAY_FAST_CYCLES >= 1U)
__NOP();
#endif
#if (DELAY_FAST_CYCLES >= 2U)
__NOP();
#endif
#if (DELAY_FAST_CYCLES >= 3U)
__NOP();
#endif
}
#ifdef __cplusplus
}
#endif
#endif /* __DAP_H__ */

View File

@ -0,0 +1,50 @@
#ifndef __CMSIS_COMPILER_H__
#define __CMSIS_COMPILER_H__
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE static inline __attribute__((always_inline))
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline __attribute__((always_inline))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U
#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U
#define GPIO_PIN_REG_2 PERIPHS_IO_MUX_GPIO2_U
#define GPIO_PIN_REG_3 PERIPHS_IO_MUX_U0RXD_U
#define GPIO_PIN_REG_4 PERIPHS_IO_MUX_GPIO4_U
#define GPIO_PIN_REG_5 PERIPHS_IO_MUX_GPIO5_U
#define GPIO_PIN_REG_6 PERIPHS_IO_MUX_SD_CLK_U
#define GPIO_PIN_REG_7 PERIPHS_IO_MUX_SD_DATA0_U
#define GPIO_PIN_REG_8 PERIPHS_IO_MUX_SD_DATA1_U
#define GPIO_PIN_REG_9 PERIPHS_IO_MUX_SD_DATA2_U
#define GPIO_PIN_REG_10 PERIPHS_IO_MUX_SD_DATA3_U
#define GPIO_PIN_REG_11 PERIPHS_IO_MUX_SD_CMD_U
#define GPIO_PIN_REG_12 PERIPHS_IO_MUX_MTDI_U
#define GPIO_PIN_REG_13 PERIPHS_IO_MUX_MTCK_U
#define GPIO_PIN_REG_14 PERIPHS_IO_MUX_MTMS_U
#define GPIO_PIN_REG_15 PERIPHS_IO_MUX_MTDO_U
#define GPIO_PIN_REG_16 PAD_XPD_DCDC_CONF
#define GPIO_PIN_REG(i) \
(i==0) ? GPIO_PIN_REG_0: \
(i==1) ? GPIO_PIN_REG_1: \
(i==2) ? GPIO_PIN_REG_2: \
(i==3) ? GPIO_PIN_REG_3: \
(i==4) ? GPIO_PIN_REG_4: \
(i==5) ? GPIO_PIN_REG_5: \
(i==6) ? GPIO_PIN_REG_6: \
(i==7) ? GPIO_PIN_REG_7: \
(i==8) ? GPIO_PIN_REG_8: \
(i==9) ? GPIO_PIN_REG_9: \
(i==10)? GPIO_PIN_REG_10: \
(i==11)? GPIO_PIN_REG_11: \
(i==12)? GPIO_PIN_REG_12: \
(i==13)? GPIO_PIN_REG_13: \
(i==14)? GPIO_PIN_REG_14: \
(i==15)? GPIO_PIN_REG_15: \
GPIO_PIN_REG_16
#endif

View File

@ -0,0 +1,565 @@
/**
* @brief Made some simple modifications to the official UART
*
*/
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _DRIVER_UART_H_
#define _DRIVER_UART_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/queue.h"
#define UART_FIFO_LEN (128) /*!< Length of the hardware FIFO buffers */
#define UART_INTR_MASK 0x1ff /*!< Mask of all UART interrupts */
#define UART_LINE_INV_MASK (0x3f << 19) /*!< TBD */
#define UART_INVERSE_DISABLE (0x0) /*!< Disable UART signal inverse*/
#define UART_INVERSE_RXD (BIT(19)) /*!< UART RXD input inverse*/
#define UART_INVERSE_CTS (BIT(20)) /*!< UART CTS input inverse*/
#define UART_INVERSE_TXD (BIT(22)) /*!< UART TXD output inverse*/
#define UART_INVERSE_RTS (BIT(23)) /*!< UART RTS output inverse*/
/**
* @brief UART mode selection
*/
typedef enum {
UART_MODE_UART = 0x00, /*!< mode: regular UART mode*/
} uart_mode_t;
/**
* @brief UART word length constants
*/
typedef enum {
UART_DATA_5_BITS = 0x0, /*!< word length: 5bits*/
UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/
UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/
UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/
UART_DATA_BITS_MAX = 0x4,
} uart_word_length_t;
/**
* @brief UART stop bits number
*/
typedef enum {
UART_STOP_BITS_1 = 0x1, /*!< stop bit: 1bit*/
UART_STOP_BITS_1_5 = 0x2, /*!< stop bit: 1.5bits*/
UART_STOP_BITS_2 = 0x3, /*!< stop bit: 2bits*/
UART_STOP_BITS_MAX = 0x4,
} uart_stop_bits_t;
/**
* @brief UART peripheral number
*/
typedef enum {
UART_NUM_0 = 0x0,
UART_NUM_1 = 0x1,
UART_NUM_MAX,
} uart_port_t;
/**
* @brief UART parity constants
*/
typedef enum {
UART_PARITY_DISABLE = 0x0, /*!< Disable UART parity*/
UART_PARITY_EVEN = 0x2, /*!< Enable UART even parity*/
UART_PARITY_ODD = 0x3 /*!< Enable UART odd parity*/
} uart_parity_t;
/**
* @brief UART hardware flow control modes
*/
typedef enum {
UART_HW_FLOWCTRL_DISABLE = 0x0, /*!< disable hardware flow control*/
UART_HW_FLOWCTRL_RTS = 0x1, /*!< enable RX hardware flow control (rts)*/
UART_HW_FLOWCTRL_CTS = 0x2, /*!< enable TX hardware flow control (cts)*/
UART_HW_FLOWCTRL_CTS_RTS = 0x3, /*!< enable hardware flow control*/
UART_HW_FLOWCTRL_MAX = 0x4,
} uart_hw_flowcontrol_t;
/**
* @brief UART configuration parameters for my_uart_param_config function
*/
typedef struct {
int baud_rate; /*!< UART baud rate*/
uart_word_length_t data_bits; /*!< UART byte size*/
uart_parity_t parity; /*!< UART parity mode*/
uart_stop_bits_t stop_bits; /*!< UART stop bits*/
uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode (cts/rts)*/
uint8_t rx_flow_ctrl_thresh; /*!< UART HW RTS threshold*/
} uart_config_t;
/**
* @brief UART interrupt configuration parameters for my_uart_intr_config function
*/
typedef struct {
uint32_t intr_enable_mask; /*!< UART interrupt enable mask, choose from UART_XXXX_INT_ENA_M under UART_INT_ENA_REG(i), connect with bit-or operator*/
uint8_t rx_timeout_thresh; /*!< UART timeout interrupt threshold (unit: time of sending one byte)*/
uint8_t txfifo_empty_intr_thresh; /*!< UART TX empty interrupt threshold.*/
uint8_t rxfifo_full_thresh; /*!< UART RX full interrupt threshold.*/
} uart_intr_config_t;
/**
* @brief UART event types used in the ring buffer
*/
typedef enum {
UART_DATA, /*!< UART data event*/
UART_BUFFER_FULL, /*!< UART RX buffer full event*/
UART_FIFO_OVF, /*!< UART FIFO overflow event*/
UART_FRAME_ERR, /*!< UART RX frame error event*/
UART_PARITY_ERR, /*!< UART RX parity event*/
UART_EVENT_MAX, /*!< UART event max index*/
} uart_event_type_t;
/**
* @brief Event structure used in UART event queue
*/
typedef struct {
uart_event_type_t type; /*!< UART event type */
size_t size; /*!< UART data size for UART_DATA event*/
} uart_event_t;
/**
* @brief Set UART data bits.
*
* @param uart_num Uart port number.
* @param data_bit Uart data bits.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit);
/**
* @brief Get UART data bits.
*
* @param uart_num Uart port number.
* @param data_bit Pointer to accept value of UART data bits.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_word_length(uart_port_t uart_num, uart_word_length_t *data_bit);
/**
* @brief Set UART stop bits.
*
* @param uart_num Uart port number
* @param stop_bits Uart stop bits
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bits);
/**
* @brief Get UART stop bits.
*
* @param uart_num Uart port number.
* @param stop_bits Pointer to accept value of UART stop bits.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t *stop_bits);
/**
* @brief Set UART parity mode.
*
* @param uart_num Uart port number.
* @param parity_mode The enum of uart parity configuration.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode);
/**
* @brief Get UART parity mode.
*
* @param uart_num Uart port number
* @param parity_mode Pointer to accept value of UART parity mode.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_parity(uart_port_t uart_num, uart_parity_t *parity_mode);
/**
* @brief Set UART baud rate.
*
* @param uart_num Uart port number
* @param baudrate UART baud rate.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate);
/**
* @brief Get UART baud rate.
*
* @param uart_num Uart port number.
* @param baudrate Pointer to accept value of Uart baud rate.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate);
/**
* @brief Set UART line inverse mode
*
* @param uart_num UART_NUM_0
* @param inverse_mask Choose the wires that need to be inverted.
* Inverse_mask should be chosen from
* UART_INVERSE_RXD / UART_INVERSE_TXD / UART_INVERSE_RTS / UART_INVERSE_CTS,
* combined with OR operation.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask);
/**
* @brief Configure Hardware flow control.
*
* @param uart_num Uart port number.
* @param flow_ctrl Hardware flow control mode.
* @param rx_thresh Threshold of Hardware flow control.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh);
/**
* @brief Get hardware flow control mode
*
* @param uart_num Uart port number.
* @param flow_ctrl Option for different flow control mode.
*
* @return
* - ESP_OK Success, result will be put in (*flow_ctrl)
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t *flow_ctrl);
/**
* @brief UART0 swap.
* Use MTCK as UART0 RX, MTDO as UART0 TX, so ROM log will not output from
* this new UART0. We also need to use MTDO (U0RTS) and MTCK (U0CTS) as UART0 in hardware.
*
* @return
* - ESP_OK Success
*/
esp_err_t my_uart_enable_swap(void);
/**
* @brief Disable UART0 swap.
* Use the original UART0, not MTCK and MTDO.
*
* @return
* - ESP_OK Success
*/
esp_err_t my_uart_disable_swap(void);
/**
* @brief Clear uart interrupts status.
*
* @param uart_num Uart port number.
* @param mask Uart interrupt bits mask.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_clear_intr_status(uart_port_t uart_num, uint32_t mask);
/**
* @brief Set UART interrupt enable
*
* @param uart_num Uart port number
* @param enable_mask Bit mask of the enable bits.
* The bit mask should be composed from the fields of register UART_INT_ENA_REG.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask);
/**
* @brief Clear UART interrupt enable bits
*
* @param uart_num Uart port number
* @param disable_mask Bit mask of the disable bits.
* The bit mask should be composed from the fields of register UART_INT_ENA_REG.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask);
/**
* @brief Enable UART RX interrupt (RX_FULL & RX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_enable_rx_intr(uart_port_t uart_num);
/**
* @brief Disable UART RX interrupt (RX_FULL & RX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_disable_rx_intr(uart_port_t uart_num);
/**
* @brief Disable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_disable_tx_intr(uart_port_t uart_num);
/**
* @brief Enable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0
* @param enable 1: enable; 0: disable
* @param thresh Threshold of TX interrupt, 0 ~ UART_FIFO_LEN
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh);
/**
* @brief Register UART interrupt handler (ISR).
*
* @param uart_num UART_NUM_0
* @param fn Interrupt handler function.
* @param arg parameter for handler function
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_isr_register(uart_port_t uart_num, void (*fn)(void *), void *arg);
/**
* @brief Config Common parameters of serial ports.
*
* @param uart_num Uart port number.
* @param uart_conf Uart config parameters.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_param_config(uart_port_t uart_num, uart_config_t *uart_conf);
/**
* @brief Config types of uarts.
*
* @param uart_num Uart port number.
* @param uart_intr_conf Uart interrupt config parameters.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_intr_config(uart_port_t uart_num, uart_intr_config_t *uart_intr_conf);
/**
* @brief Install UART driver.
*
* @note Rx_buffer_size should be greater than UART_FIFO_LEN. Tx_buffer_size should be either zero or greater than UART_FIFO_LEN.
*
* @param uart_num Uart port number.
* @param rx_buffer_size UART RX ring buffer size.
* @param tx_buffer_size UART TX ring buffer size.
* If set to zero, driver will not use TX buffer, TX function will block task until all data have been sent out.
* @param queue_size UART event queue size/depth.
* @param uart_queue UART event queue handle (out param). On success, a new queue handle is written here to provide
* access to UART events. If set to NULL, driver will not use an event queue.
* @param no_use Invalid parameters, just to fit some modules.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, QueueHandle_t *uart_queue, int no_use);
/**
* @brief Uninstall UART driver.
*
* @param uart_num Uart port number.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_driver_delete(uart_port_t uart_num);
/**
* @brief Waiting for the last byte of data to be sent
*
* @param uart_num Uart port number.
* @param ticks_to_wait Timeout, count in RTOS ticks
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait);
/**
* @brief Send data to the UART port from a given buffer and length.
*
* This function will not wait for enough space in TX FIFO. It will just fill the available TX FIFO and return when the FIFO is full.
* @note This function should only be used when UART TX buffer is not enabled.
*
* @param uart_num Uart port number.
* @param buffer data buffer address
* @param len data length to send
*
* @return
* - (-1) Parameter error
* - OTHERS (>=0) The number of bytes pushed to the TX FIFO
*/
int my_uart_tx_chars(uart_port_t uart_num, const char *buffer, uint32_t len);
/**
* @brief Send data to the UART port from a given buffer and length,
*
* If the UART driver's parameter 'tx_buffer_size' is set to zero:
* This function will not return until all the data have been sent out, or at least pushed into TX FIFO.
*
* Otherwise, if the 'tx_buffer_size' > 0, this function will return after copying all the data to tx ring buffer,
* UART ISR will then move data from the ring buffer to TX FIFO gradually.
*
* @param uart_num Uart port number.
* @param src data buffer address
* @param size data length to send
*
* @return
* - (-1) Parameter error
* - OTHERS (>=0) The number of bytes pushed to the TX FIFO
*/
int my_uart_write_bytes(uart_port_t uart_num, const char *src, size_t size);
/**
* @brief UART read bytes from UART buffer
*
* @param uart_num Uart port number.
* @param buf pointer to the buffer.
* @param length data length
* @param ticks_to_wait sTimeout, count in RTOS ticks
*
* @return
* - (-1) Error
* - OTHERS (>=0) The number of bytes read from UART FIFO
*/
int my_uart_read_bytes(uart_port_t uart_num, uint8_t *buf, uint32_t length, TickType_t ticks_to_wait);
/**
* @brief Alias of my_uart_flush_input.
* UART ring buffer flush. This will discard all data in the UART RX buffer.
* @note Instead of waiting the data sent out, this function will clear UART rx buffer.
* In order to send all the data in tx FIFO, we can use my_uart_wait_tx_done function.
* @param uart_num UART port number.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_flush(uart_port_t uart_num);
/**
* @brief Clear input buffer, discard all the data is in the ring-buffer.
* @note In order to send all the data in tx FIFO, we can use my_uart_wait_tx_done function.
* @param uart_num UART port number.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_flush_input(uart_port_t uart_num);
/**
* @brief UART get RX ring buffer cached data length
*
* @param uart_num UART port number.
* @param size Pointer of size_t to accept cached data length
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_buffered_data_len(uart_port_t uart_num, size_t *size);
/**
* @brief UART set threshold timeout for TOUT feature
*
* @param uart_num Uart number to configure
* @param tout_thresh This parameter defines timeout threshold in uart symbol periods. The maximum value of threshold is 126.
* tout_thresh = 1, defines TOUT interrupt timeout equal to transmission time of one symbol (~11 bit) on current baudrate.
* If the time is expired the UART_RXFIFO_TOUT_INT interrupt is triggered. If tout_thresh == 0,
* the TOUT feature is disabled.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh);
#ifdef __cplusplus
}
#endif
#endif // _DRIVER_UART_H_

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 1. December 2017
* $Revision: V2.0.0
*
* Project: CMSIS-DAP Source
* Title: DAP_vendor.c CMSIS-DAP Vendor Commands
*
*---------------------------------------------------------------------------*/
#include "DAP_config.h"
#include "DAP.h"
//**************************************************************************************************
/**
\defgroup DAP_Vendor_Adapt_gr Adapt Vendor Commands
\ingroup DAP_Vendor_gr
@{
The file DAP_vendor.c provides template source code for extension of a Debug Unit with
Vendor Commands. Copy this file to the project folder of the Debug Unit and add the
file to the MDK-ARM project under the file group Configuration.
*/
/** Process DAP Vendor Command and prepare Response Data
\param request pointer to request data
\param response pointer to response data
\return number of bytes in response (lower 16 bits)
number of bytes in request (upper 16 bits)
*/
uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) {
uint32_t num = (1U << 16) | 1U;
*response++ = *request; // copy Command ID
switch (*request++) { // first byte in request is Command ID
case ID_DAP_Vendor0:
#if 0 // example user command
num += 1U << 16; // increment request count
if (*request == 1U) { // when first command data byte is 1
*response++ = 'X'; // send 'X' as response
num++; // increment response count
}
#endif
break;
case ID_DAP_Vendor1: break;
case ID_DAP_Vendor2: break;
case ID_DAP_Vendor3: break;
case ID_DAP_Vendor4: break;
case ID_DAP_Vendor5: break;
case ID_DAP_Vendor6: break;
case ID_DAP_Vendor7: break;
case ID_DAP_Vendor8: break;
case ID_DAP_Vendor9: break;
case ID_DAP_Vendor10: break;
case ID_DAP_Vendor11: break;
case ID_DAP_Vendor12: break;
case ID_DAP_Vendor13: break;
case ID_DAP_Vendor14: break;
case ID_DAP_Vendor15: break;
case ID_DAP_Vendor16: break;
case ID_DAP_Vendor17: break;
case ID_DAP_Vendor18: break;
case ID_DAP_Vendor19: break;
case ID_DAP_Vendor20: break;
case ID_DAP_Vendor21: break;
case ID_DAP_Vendor22: break;
case ID_DAP_Vendor23: break;
case ID_DAP_Vendor24: break;
case ID_DAP_Vendor25: break;
case ID_DAP_Vendor26: break;
case ID_DAP_Vendor27: break;
case ID_DAP_Vendor28: break;
case ID_DAP_Vendor29: break;
case ID_DAP_Vendor30: break;
case ID_DAP_Vendor31: break;
}
return (num);
}
///@}

View File

@ -0,0 +1,370 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 1. December 2017
* $Revision: V2.0.0
*
* Project: CMSIS-DAP Source
* Title: JTAG_DP.c CMSIS-DAP JTAG DP I/O
*
*---------------------------------------------------------------------------*/
#include "DAP_config.h"
#include "DAP.h"
// JTAG Macros
#define PIN_TCK_SET PIN_SWCLK_TCK_SET
#define PIN_TCK_CLR PIN_SWCLK_TCK_CLR
#define PIN_TMS_SET PIN_SWDIO_TMS_SET
#define PIN_TMS_CLR PIN_SWDIO_TMS_CLR
#define JTAG_CYCLE_TCK() \
PIN_TCK_CLR(); \
PIN_DELAY(); \
PIN_TCK_SET(); \
PIN_DELAY()
#define JTAG_CYCLE_TDI(tdi) \
PIN_TDI_OUT(tdi); \
PIN_TCK_CLR(); \
PIN_DELAY(); \
PIN_TCK_SET(); \
PIN_DELAY()
#define JTAG_CYCLE_TDO(tdo) \
PIN_TCK_CLR(); \
PIN_DELAY(); \
tdo = PIN_TDO_IN(); \
PIN_TCK_SET(); \
PIN_DELAY()
#define JTAG_CYCLE_TDIO(tdi,tdo) \
PIN_TDI_OUT(tdi); \
PIN_TCK_CLR(); \
PIN_DELAY(); \
tdo = PIN_TDO_IN(); \
PIN_TCK_SET(); \
PIN_DELAY()
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
#if (DAP_JTAG != 0)
// Generate JTAG Sequence
// info: sequence information
// tdi: pointer to TDI generated data
// tdo: pointer to TDO captured data
// return: none
void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo) {
uint32_t i_val;
uint32_t o_val;
uint32_t bit;
uint32_t n, k;
n = info & JTAG_SEQUENCE_TCK;
if (n == 0U) {
n = 64U;
}
if (info & JTAG_SEQUENCE_TMS) {
PIN_TMS_SET();
} else {
PIN_TMS_CLR();
}
while (n) {
i_val = *tdi++;
o_val = 0U;
for (k = 8U; k && n; k--, n--) {
JTAG_CYCLE_TDIO(i_val, bit);
i_val >>= 1;
o_val >>= 1;
o_val |= bit << 7;
}
o_val >>= k;
if (info & JTAG_SEQUENCE_TDO) {
*tdo++ = (uint8_t)o_val;
}
}
}
// JTAG Set IR
// ir: IR value
// return: none
#define JTAG_IR_Function(speed) /**/ \
static void JTAG_IR_##speed (uint32_t ir) { \
uint32_t n; \
\
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \
PIN_TMS_CLR(); \
JTAG_CYCLE_TCK(); /* Capture-IR */ \
JTAG_CYCLE_TCK(); /* Shift-IR */ \
\
PIN_TDI_OUT(1U); \
for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass before data */ \
} \
for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1U; n; n--) { \
JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \
ir >>= 1; \
} \
n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \
if (n) { \
JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \
PIN_TDI_OUT(1U); \
for (--n; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass after data */ \
} \
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \
} else { \
PIN_TMS_SET(); \
JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \
} \
\
JTAG_CYCLE_TCK(); /* Update-IR */ \
PIN_TMS_CLR(); \
JTAG_CYCLE_TCK(); /* Idle */ \
PIN_TDI_OUT(1U); \
}
// JTAG Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
#define JTAG_TransferFunction(speed) /**/ \
static uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) { \
uint32_t ack; \
uint32_t bit; \
uint32_t val; \
uint32_t n; \
\
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
PIN_TMS_CLR(); \
JTAG_CYCLE_TCK(); /* Capture-DR */ \
JTAG_CYCLE_TCK(); /* Shift-DR */ \
\
for (n = DAP_Data.jtag_dev.index; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass before data */ \
} \
\
JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \
ack = bit << 1; \
JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \
ack |= bit << 0; \
JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \
ack |= bit << 2; \
\
if (ack != DAP_TRANSFER_OK) { \
/* Exit on error */ \
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Exit1-DR */ \
goto exit; \
} \
\
if (request & DAP_TRANSFER_RnW) { \
/* Read Transfer */ \
val = 0U; \
for (n = 31U; n; n--) { \
JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \
val |= bit << 31; \
val >>= 1; \
} \
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \
if (n) { \
JTAG_CYCLE_TDO(bit); /* Get D31 */ \
for (--n; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass after data */ \
} \
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
} else { \
PIN_TMS_SET(); \
JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \
} \
val |= bit << 31; \
if (data) { *data = val; } \
} else { \
/* Write Transfer */ \
val = *data; \
for (n = 31U; n; n--) { \
JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \
val >>= 1; \
} \
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \
if (n) { \
JTAG_CYCLE_TDI(val); /* Set D31 */ \
for (--n; n; n--) { \
JTAG_CYCLE_TCK(); /* Bypass after data */ \
} \
PIN_TMS_SET(); \
JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
} else { \
PIN_TMS_SET(); \
JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \
} \
} \
\
exit: \
JTAG_CYCLE_TCK(); /* Update-DR */ \
PIN_TMS_CLR(); \
JTAG_CYCLE_TCK(); /* Idle */ \
PIN_TDI_OUT(1U); \
\
/* Capture Timestamp */ \
if (request & DAP_TRANSFER_TIMESTAMP) { \
DAP_Data.timestamp = TIMESTAMP_GET(); \
} \
\
/* Idle cycles */ \
n = DAP_Data.transfer.idle_cycles; \
while (n--) { \
JTAG_CYCLE_TCK(); /* Idle */ \
} \
\
return ((uint8_t)ack); \
}
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_FAST()
JTAG_IR_Function(Fast)
JTAG_TransferFunction(Fast)
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
JTAG_IR_Function(Slow)
JTAG_TransferFunction(Slow)
// JTAG Read IDCODE register
// return: value read
uint32_t JTAG_ReadIDCode (void) {
uint32_t bit;
uint32_t val;
uint32_t n;
PIN_TMS_SET();
JTAG_CYCLE_TCK(); /* Select-DR-Scan */
PIN_TMS_CLR();
JTAG_CYCLE_TCK(); /* Capture-DR */
JTAG_CYCLE_TCK(); /* Shift-DR */
for (n = DAP_Data.jtag_dev.index; n; n--) {
JTAG_CYCLE_TCK(); /* Bypass before data */
}
val = 0U;
for (n = 31U; n; n--) {
JTAG_CYCLE_TDO(bit); /* Get D0..D30 */
val |= bit << 31;
val >>= 1;
}
PIN_TMS_SET();
JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */
val |= bit << 31;
JTAG_CYCLE_TCK(); /* Update-DR */
PIN_TMS_CLR();
JTAG_CYCLE_TCK(); /* Idle */
return (val);
}
// JTAG Write ABORT register
// data: value to write
// return: none
void JTAG_WriteAbort (uint32_t data) {
uint32_t n;
PIN_TMS_SET();
JTAG_CYCLE_TCK(); /* Select-DR-Scan */
PIN_TMS_CLR();
JTAG_CYCLE_TCK(); /* Capture-DR */
JTAG_CYCLE_TCK(); /* Shift-DR */
for (n = DAP_Data.jtag_dev.index; n; n--) {
JTAG_CYCLE_TCK(); /* Bypass before data */
}
PIN_TDI_OUT(0U);
JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */
JTAG_CYCLE_TCK(); /* Set A2=0 */
JTAG_CYCLE_TCK(); /* Set A3=0 */
for (n = 31U; n; n--) {
JTAG_CYCLE_TDI(data); /* Set D0..D30 */
data >>= 1;
}
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U;
if (n) {
JTAG_CYCLE_TDI(data); /* Set D31 */
for (--n; n; n--) {
JTAG_CYCLE_TCK(); /* Bypass after data */
}
PIN_TMS_SET();
JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */
} else {
PIN_TMS_SET();
JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */
}
JTAG_CYCLE_TCK(); /* Update-DR */
PIN_TMS_CLR();
JTAG_CYCLE_TCK(); /* Idle */
PIN_TDI_OUT(1U);
}
// JTAG Set IR
// ir: IR value
// return: none
void JTAG_IR (uint32_t ir) {
if (DAP_Data.fast_clock) {
JTAG_IR_Fast(ir);
} else {
JTAG_IR_Slow(ir);
}
}
// JTAG Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) {
if (DAP_Data.fast_clock) {
return JTAG_TransferFast(request, data);
} else {
return JTAG_TransferSlow(request, data);
}
}
#endif /* (DAP_JTAG != 0) */

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

@ -0,0 +1,946 @@
/**
* @brief Modify this file to fit esp8266 Uart
*
*/
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 1. December 2017
* $Revision: V2.0.0
*
* Project: CMSIS-DAP Source
* Title: SWO.c CMSIS-DAP SWO I/O
*
*---------------------------------------------------------------------------*/
#include "DAP_config.h"
#include "DAP.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "uart_modify.h"
EventGroupHandle_t kSWO_Thread_event_group;
EventGroupHandle_t kUART_Monitoe_event_group;
#define SWO_GOT_DATA BIT0
#define SWO_ERROR_TIME_OUT BIT1
#define UART_GOT_DATA BIT0
#if (SWO_STREAM != 0)
#ifdef DAP_FW_V1
#error "SWO Streaming Trace not supported in DAP V1!"
#endif
#endif
#if (SWO_UART != 0)
#ifndef USART_PORT
#define USART_PORT UART_NUM_0 /* USART Port Number */
#endif
static uint8_t USART_Ready = 0U;
#endif /* (SWO_UART != 0) */
#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
#define SWO_STREAM_TIMEOUT (50 / portTICK_RATE_MS) /* Stream timeout in ms */
#define USB_BLOCK_SIZE 512U /* USB Block Size */
#define TRACE_BLOCK_SIZE 64U /* Trace Block Size (2^n: 32...512) */
// Trace State
static uint8_t TraceTransport = 0U; /* Trace Transport */
static uint8_t TraceMode = 0U; /* Trace Mode */
static uint8_t TraceStatus = 0U; /* Trace Status without Errors */
static uint8_t TraceError[2] = {0U, 0U}; /* Trace Error flags (banked) */
static uint8_t TraceError_n = 0U; /* Active Trace Error bank */
// Trace Buffer
static uint8_t TraceBuf[SWO_BUFFER_SIZE]; /* Trace Buffer (must be 2^n) */
static volatile uint32_t TraceIndexI = 0U; /* Incoming Trace Index */
static volatile uint32_t TraceIndexO = 0U; /* Outgoing Trace Index */
static volatile uint8_t TraceUpdate; /* Trace Update Flag */
static uint32_t TraceBlockSize; /* Current Trace Block Size */
#if (TIMESTAMP_CLOCK != 0U)
// Trace Timestamp
static volatile struct
{
uint32_t index;
uint32_t tick;
} TraceTimestamp;
#endif
// Trace Helper functions
static void ClearTrace(void);
static void ResumeTrace(void);
static uint32_t GetTraceCount(void);
static uint8_t GetTraceStatus(void);
void SetTraceError(uint8_t flag);
#if (SWO_STREAM != 0)
static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */
static uint32_t TransferSize; /* Current Transfer Size */
#endif
#if (SWO_UART != 0)
void usart_monitor_task(void *argument)
{
uint32_t index_i;
uint32_t index_o;
uint32_t count;
uint32_t num;
uint32_t flags;
kUART_Monitoe_event_group = xEventGroupCreate();
for (;;)
{
flags = xEventGroupWaitBits(kUART_Monitoe_event_group, UART_GOT_DATA,
pdTRUE, pdFALSE, portMAX_DELAY);
if (flags & UART_GOT_DATA)
{
#if (TIMESTAMP_CLOCK != 0U)
TraceTimestamp.tick = TIMESTAMP_GET();
#endif
index_o = TraceIndexO;
index_i = TraceIndexI;
index_i += TraceBlockSize;
TraceIndexI = index_i;
#if (TIMESTAMP_CLOCK != 0U)
TraceTimestamp.index = index_i;
#endif
num = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U));
// num is the number of bytes we need to read
// (to achieve the size of TRACE_BLOCK_SIZE)
count = index_i - index_o;
// Amount of data that has not been processed yet
// (SWO_BUFFER_SIZE-num): the remaining usable length of the buffer after reading this data
if (count <= (SWO_BUFFER_SIZE - num))
{
index_i &= SWO_BUFFER_SIZE - 1U;
TraceBlockSize = num;
my_uart_read_bytes(USART_PORT, &TraceBuf[index_i], num, 20 / portTICK_RATE_MS);
//pUSART->Receive(&TraceBuf[index_i], num);
}
else
{
// Not enough buffers
TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED;
}
TraceUpdate = 1U;
#if (SWO_STREAM != 0)
if (TraceTransport == 2U)
{
if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U))))
{
xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
}
}
#endif
}
}
// if (event & ARM_USART_EVENT_RX_OVERFLOW)
// {
// SetTraceError(DAP_SWO_BUFFER_OVERRUN);
// }
// if (event & (ARM_USART_EVENT_RX_BREAK |
// ARM_USART_EVENT_RX_FRAMING_ERROR |
// ARM_USART_EVENT_RX_PARITY_ERROR))
// {
// SetTraceError(DAP_SWO_STREAM_ERROR);
// }
}
// Enable or disable UART SWO Mode
// enable: enable flag
// return: 1 - Success, 0 - Error
__WEAK uint32_t UART_SWO_Mode(uint32_t enable)
{
int32_t status;
USART_Ready = 0U;
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
my_uart_param_config(USART_PORT, &uart_config);
#define BUF_SIZE (1024)
my_uart_driver_install(USART_PORT, BUF_SIZE, 0, 0, NULL, 0);
if (enable != 0U)
{
my_uart_param_config(USART_PORT, &uart_config);
status = my_uart_driver_install(USART_PORT, BUF_SIZE, 0, 0, NULL, 0);
if (status != ESP_OK)
{
return (0U);
}
}
else
{
my_uart_driver_delete(USART_PORT);
}
return (1U);
}
// Configure UART SWO Baudrate
// baudrate: requested baudrate
// return: actual baudrate or 0 when not configured
__WEAK uint32_t UART_SWO_Baudrate(uint32_t baudrate)
{
int32_t status;
uint32_t index;
uint32_t num;
if (baudrate > SWO_UART_MAX_BAUDRATE)
{
baudrate = SWO_UART_MAX_BAUDRATE;
}
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
{
size_t len = 0;
my_uart_get_buffered_data_len(USART_PORT, &len);
my_uart_flush(USART_PORT);
TraceIndexI += len;
// pUSART->Control(ARM_USART_CONTROL_RX, 0U);
// if (pUSART->GetStatus().rx_busy)
// {
// TraceIndexI += pUSART->GetRxCount();
// pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
// }
}
/////////////
status = my_uart_set_baudrate(USART_PORT, baudrate);
if (status == ESP_OK)
{
USART_Ready = 1U;
}
else
{
USART_Ready = 0U;
return (0U);
}
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
{
if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U)
{
index = TraceIndexI & (SWO_BUFFER_SIZE - 1U);
num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U));
TraceBlockSize = num;
//pUSART->Receive(&TraceBuf[index], num);
my_uart_read_bytes(USART_PORT, &TraceBuf[index], num, 20 / portTICK_RATE_MS);
}
//pUSART->Control(ARM_USART_CONTROL_RX, 1U); ////TODO:
}
return (baudrate);
}
// Control UART SWO Capture
// active: active flag
// return: 1 - Success, 0 - Error
__WEAK uint32_t UART_SWO_Control(uint32_t active)
{
int32_t status;
if (active)
{
if (!USART_Ready)
{
return (0U);
}
TraceBlockSize = 1U;
status = my_uart_read_bytes(USART_PORT, &TraceBuf[0], 1U, 20 / portTICK_RATE_MS);
if (status == ESP_FAIL)
{
return (0U);
}
// status = pUSART->Control(ARM_USART_CONTROL_RX, 1U);
// if (status != ARM_DRIVER_OK)
// {
// return (0U);
// } ////TODO:
}
else
{
size_t len = 0;
my_uart_get_buffered_data_len(USART_PORT, &len);
my_uart_flush(USART_PORT);
TraceIndexI += len;
// pUSART->Control(ARM_USART_CONTROL_RX, 0U);
// if (pUSART->GetStatus().rx_busy)
// {
// TraceIndexI += pUSART->GetRxCount();
// pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
// }
}
return (1U);
}
// Start UART SWO Capture
// buf: pointer to buffer for capturing
// num: number of bytes to capture
__WEAK void UART_SWO_Capture(uint8_t *buf, uint32_t num)
{
TraceBlockSize = num;
my_uart_read_bytes(USART_PORT, buf, num, 20 / portTICK_RATE_MS);
}
// Get UART SWO Pending Trace Count
// return: number of pending trace data bytes
__WEAK uint32_t UART_SWO_GetCount(void)
{
uint32_t count;
// if (pUSART->GetStatus().rx_busy)
// {
// count = pUSART->GetRxCount();
// }
// else
// {
// count = 0U;
// }
my_uart_get_buffered_data_len(USART_PORT, &count);
return (count);
}
#endif /* (SWO_UART != 0) */
#if (SWO_MANCHESTER != 0)
// Enable or disable Manchester SWO Mode
// enable: enable flag
// return: 1 - Success, 0 - Error
__WEAK uint32_t Manchester_SWO_Mode(uint32_t enable)
{
return (0U);
}
// Configure Manchester SWO Baudrate
// baudrate: requested baudrate
// return: actual baudrate or 0 when not configured
__WEAK uint32_t Manchester_SWO_Baudrate(uint32_t baudrate)
{
return (0U);
}
// Control Manchester SWO Capture
// active: active flag
// return: 1 - Success, 0 - Error
__WEAK uint32_t Manchester_SWO_Control(uint32_t active)
{
return (0U);
}
// Start Manchester SWO Capture
// buf: pointer to buffer for capturing
// num: number of bytes to capture
__WEAK void Manchester_SWO_Capture(uint8_t *buf, uint32_t num)
{
}
// Get Manchester SWO Pending Trace Count
// return: number of pending trace data bytes
__WEAK uint32_t Manchester_SWO_GetCount(void)
{
return (0U);
}
#endif /* (SWO_MANCHESTER != 0) */
// Clear Trace Errors and Data
static void ClearTrace(void)
{
#if (SWO_STREAM != 0)
if (TraceTransport == 2U)
{
if (TransferBusy != 0U)
{
SWO_AbortTransfer();
TransferBusy = 0U;
}
}
#endif
TraceError[0] = 0U;
TraceError[1] = 0U;
TraceError_n = 0U;
TraceIndexI = 0U;
TraceIndexO = 0U;
#if (TIMESTAMP_CLOCK != 0U)
TraceTimestamp.index = 0U;
TraceTimestamp.tick = 0U;
#endif
}
// Resume Trace Capture
static void ResumeTrace(void)
{
uint32_t index_i;
uint32_t index_o;
if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED))
{
index_i = TraceIndexI;
index_o = TraceIndexO;
if ((index_i - index_o) < SWO_BUFFER_SIZE)
{
index_i &= SWO_BUFFER_SIZE - 1U;
switch (TraceMode)
{
#if (SWO_UART != 0)
case DAP_SWO_UART:
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
UART_SWO_Capture(&TraceBuf[index_i], 1U);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
Manchester_SWO_Capture(&TraceBuf[index_i], 1U);
break;
#endif
default:
break;
}
}
}
}
// Get Trace Count
// return: number of available data bytes in trace buffer
static uint32_t GetTraceCount(void)
{
uint32_t count;
if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE)
{
do
{
TraceUpdate = 0U;
count = TraceIndexI - TraceIndexO;
switch (TraceMode)
{
#if (SWO_UART != 0)
case DAP_SWO_UART:
count += UART_SWO_GetCount();
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
count += Manchester_SWO_GetCount();
break;
#endif
default:
break;
}
} while (TraceUpdate != 0U);
}
else
{
count = TraceIndexI - TraceIndexO;
}
return (count);
}
// Get Trace Status (clear Error flags)
// return: Trace Status (Active flag and Error flags)
static uint8_t GetTraceStatus(void)
{
uint8_t status;
uint32_t n;
n = TraceError_n;
TraceError_n ^= 1U;
status = TraceStatus | TraceError[n];
TraceError[n] = 0U;
return (status);
}
// Set Trace Error flag(s)
// flag: error flag(s) to set
void SetTraceError(uint8_t flag)
{
TraceError[TraceError_n] |= flag;
}
// Process SWO Transport command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t SWO_Transport(const uint8_t *request, uint8_t *response)
{
uint8_t transport;
uint32_t result;
if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U)
{
transport = *request;
switch (transport)
{
case 0U:
case 1U:
#if (SWO_STREAM != 0)
case 2U:
#endif
TraceTransport = transport;
result = 1U;
break;
default:
result = 0U;
break;
}
}
else
{
result = 0U;
}
if (result != 0U)
{
*response = DAP_OK;
}
else
{
*response = DAP_ERROR;
}
return ((1U << 16) | 1U);
}
// Process SWO Mode command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t SWO_Mode(const uint8_t *request, uint8_t *response)
{
uint8_t mode;
uint32_t result;
mode = *request;
switch (TraceMode)
{
#if (SWO_UART != 0)
case DAP_SWO_UART:
UART_SWO_Mode(0U);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
Manchester_SWO_Mode(0U);
break;
#endif
default:
break;
}
switch (mode)
{
case DAP_SWO_OFF:
result = 1U;
break;
#if (SWO_UART != 0)
case DAP_SWO_UART:
result = UART_SWO_Mode(1U);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
result = Manchester_SWO_Mode(1U);
break;
#endif
default:
result = 0U;
break;
}
if (result != 0U)
{
TraceMode = mode;
}
else
{
TraceMode = DAP_SWO_OFF;
}
TraceStatus = 0U;
if (result != 0U)
{
*response = DAP_OK;
}
else
{
*response = DAP_ERROR;
}
return ((1U << 16) | 1U);
}
// Process SWO Baudrate command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t SWO_Baudrate(const uint8_t *request, uint8_t *response)
{
uint32_t baudrate;
baudrate = (uint32_t)(*(request + 0) << 0) |
(uint32_t)(*(request + 1) << 8) |
(uint32_t)(*(request + 2) << 16) |
(uint32_t)(*(request + 3) << 24);
switch (TraceMode)
{
#if (SWO_UART != 0)
case DAP_SWO_UART:
baudrate = UART_SWO_Baudrate(baudrate);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
baudrate = Manchester_SWO_Baudrate(baudrate);
break;
#endif
default:
baudrate = 0U;
break;
}
if (baudrate == 0U)
{
TraceStatus = 0U;
}
*response++ = (uint8_t)(baudrate >> 0);
*response++ = (uint8_t)(baudrate >> 8);
*response++ = (uint8_t)(baudrate >> 16);
*response = (uint8_t)(baudrate >> 24);
return ((4U << 16) | 4U);
}
// Process SWO Control command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t SWO_Control(const uint8_t *request, uint8_t *response)
{
uint8_t active;
uint32_t result;
active = *request & DAP_SWO_CAPTURE_ACTIVE;
if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE))
{
if (active)
{
ClearTrace();
}
switch (TraceMode)
{
#if (SWO_UART != 0)
case DAP_SWO_UART:
result = UART_SWO_Control(active);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
result = Manchester_SWO_Control(active);
break;
#endif
default:
result = 0U;
break;
}
if (result != 0U)
{
TraceStatus = active;
#if (SWO_STREAM != 0)
if (TraceTransport == 2U)
{
xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
}
#endif
}
}
else
{
result = 1U;
}
if (result != 0U)
{
*response = DAP_OK;
}
else
{
*response = DAP_ERROR;
}
return ((1U << 16) | 1U);
}
// Process SWO Status command and prepare response
// response: pointer to response data
// return: number of bytes in response
uint32_t SWO_Status(uint8_t *response)
{
uint8_t status;
uint32_t count;
status = GetTraceStatus();
count = GetTraceCount();
*response++ = status;
*response++ = (uint8_t)(count >> 0);
*response++ = (uint8_t)(count >> 8);
*response++ = (uint8_t)(count >> 16);
*response = (uint8_t)(count >> 24);
return (5U);
}
// Process SWO Extended Status command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t SWO_ExtendedStatus(const uint8_t *request, uint8_t *response)
{
uint8_t cmd;
uint8_t status;
uint32_t count;
#if (TIMESTAMP_CLOCK != 0U)
uint32_t index;
uint32_t tick;
#endif
uint32_t num;
num = 0U;
cmd = *request;
if (cmd & 0x01U)
{
status = GetTraceStatus();
*response++ = status;
num += 1U;
}
if (cmd & 0x02U)
{
count = GetTraceCount();
*response++ = (uint8_t)(count >> 0);
*response++ = (uint8_t)(count >> 8);
*response++ = (uint8_t)(count >> 16);
*response++ = (uint8_t)(count >> 24);
num += 4U;
}
#if (TIMESTAMP_CLOCK != 0U)
if (cmd & 0x04U)
{
do
{
TraceUpdate = 0U;
index = TraceTimestamp.index;
tick = TraceTimestamp.tick;
} while (TraceUpdate != 0U);
*response++ = (uint8_t)(index >> 0);
*response++ = (uint8_t)(index >> 8);
*response++ = (uint8_t)(index >> 16);
*response++ = (uint8_t)(index >> 24);
*response++ = (uint8_t)(tick >> 0);
*response++ = (uint8_t)(tick >> 8);
*response++ = (uint8_t)(tick >> 16);
*response++ = (uint8_t)(tick >> 24);
num += 4U;
}
#endif
return ((1U << 16) | num);
}
// Process SWO Data command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t SWO_Data(const uint8_t *request, uint8_t *response)
{
uint8_t status;
uint32_t count;
uint32_t index;
uint32_t n, i;
status = GetTraceStatus();
count = GetTraceCount();
if (TraceTransport == 1U)
{
n = (uint32_t)(*(request + 0) << 0) |
(uint32_t)(*(request + 1) << 8);
if (n > (DAP_PACKET_SIZE - 4U))
{
n = DAP_PACKET_SIZE - 4U;
}
if (count > n)
{
count = n;
}
}
else
{
count = 0U;
}
*response++ = status;
*response++ = (uint8_t)(count >> 0);
*response++ = (uint8_t)(count >> 8);
if (TraceTransport == 1U)
{
index = TraceIndexO;
for (i = index, n = count; n; n--)
{
i &= SWO_BUFFER_SIZE - 1U;
*response++ = TraceBuf[i++];
}
TraceIndexO = index + count;
ResumeTrace();
}
return ((2U << 16) | (3U + count));
}
#if (SWO_STREAM != 0)
// SWO Data Transfer complete callback
void SWO_TransferComplete(void)
{
TraceIndexO += TransferSize;
TransferBusy = 0U;
ResumeTrace();
xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
}
// SWO Thread
void SWO_Thread(void *argument)
{
uint32_t timeout;
uint32_t flags;
uint32_t count;
uint32_t index;
uint32_t i, n;
(void)argument;
timeout = portMAX_DELAY;
kSWO_Thread_event_group = xEventGroupCreate();
for (;;)
{
flags = xEventGroupWaitBits(kSWO_Thread_event_group, SWO_GOT_DATA | SWO_ERROR_TIME_OUT,
pdTRUE, pdFALSE, timeout);
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
{
timeout = SWO_STREAM_TIMEOUT;
}
else
{
timeout = portMAX_DELAY;
flags = SWO_ERROR_TIME_OUT;
}
if (TransferBusy == 0U)
{
count = GetTraceCount();
if (count != 0U)
{
index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
n = SWO_BUFFER_SIZE - index;
if (count > n)
{
count = n;
}
if ((flags & SWO_ERROR_TIME_OUT) == 0)
{
i = index & (USB_BLOCK_SIZE - 1U);
if (i == 0U)
{
count &= ~(USB_BLOCK_SIZE - 1U);
// Take down to the nearest number that is a multiple of USB_BLOCK_SIZE
}
else
{
n = USB_BLOCK_SIZE - i;
if (count >= n)
{
count = n;
}
else
{
count = 0U;
}
}
}
if (count != 0U)
{
TransferSize = count;
TransferBusy = 1U;
SWO_QueueTransfer(&TraceBuf[index], count); //through USB
}
}
}
}
}
#endif /* (SWO_STREAM != 0) */
#endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */

View File

@ -0,0 +1,286 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 1. December 2017
* $Revision: V2.0.0
*
* Project: CMSIS-DAP Source
* Title: SW_DP.c CMSIS-DAP SW DP I/O
*
*---------------------------------------------------------------------------*/
#include "DAP_config.h"
#include "DAP.h"
// SW Macros
#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR
#define SW_CLOCK_CYCLE() \
PIN_SWCLK_CLR(); \
PIN_DELAY(); \
PIN_SWCLK_SET(); \
PIN_DELAY()
#define SW_WRITE_BIT(bit) \
PIN_SWDIO_OUT(bit); \
PIN_SWCLK_CLR(); \
PIN_DELAY(); \
PIN_SWCLK_SET(); \
PIN_DELAY()
#define SW_READ_BIT(bit) \
PIN_SWCLK_CLR(); \
PIN_DELAY(); \
bit = PIN_SWDIO_IN(); \
PIN_SWCLK_SET(); \
PIN_DELAY()
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
// Generate SWJ Sequence
// count: sequence bit count
// data: pointer to sequence bit data
// return: none
#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
void SWJ_Sequence (uint32_t count, const uint8_t *data) {
uint32_t val;
uint32_t n;
val = 0U;
n = 0U;
while (count--) {
if (n == 0U) {
val = *data++;
n = 8U;
}
if (val & 1U) {
PIN_SWDIO_TMS_SET();
} else {
PIN_SWDIO_TMS_CLR();
}
SW_CLOCK_CYCLE();
val >>= 1;
n--;
}
}
#endif
// Generate SWD Sequence
// info: sequence information
// swdo: pointer to SWDIO generated data
// swdi: pointer to SWDIO captured data
// return: none
#if (DAP_SWD != 0)
void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) {
uint32_t val;
uint32_t bit;
uint32_t n, k;
n = info & SWD_SEQUENCE_CLK;
if (n == 0U) {
n = 64U;
}
if (info & SWD_SEQUENCE_DIN) {
while (n) {
val = 0U;
for (k = 8U; k && n; k--, n--) {
SW_READ_BIT(bit);
val >>= 1;
val |= bit << 7;
}
val >>= k;
*swdi++ = (uint8_t)val;
}
} else {
while (n) {
val = *swdo++;
for (k = 8U; k && n; k--, n--) {
SW_WRITE_BIT(val);
val >>= 1;
}
}
}
}
#endif
#if (DAP_SWD != 0)
// SWD Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
#define SWD_TransferFunction(speed) /**/ \
static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
uint32_t ack; \
uint32_t bit; \
uint32_t val; \
uint32_t parity; \
\
uint32_t n; \
\
/* Packet Request */ \
parity = 0U; \
SW_WRITE_BIT(1U); /* Start Bit */ \
bit = request >> 0; \
SW_WRITE_BIT(bit); /* APnDP Bit */ \
parity += bit; \
bit = request >> 1; \
SW_WRITE_BIT(bit); /* RnW Bit */ \
parity += bit; \
bit = request >> 2; \
SW_WRITE_BIT(bit); /* A2 Bit */ \
parity += bit; \
bit = request >> 3; \
SW_WRITE_BIT(bit); /* A3 Bit */ \
parity += bit; \
SW_WRITE_BIT(parity); /* Parity Bit */ \
SW_WRITE_BIT(0U); /* Stop Bit */ \
SW_WRITE_BIT(1U); /* Park Bit */ \
\
/* Turnaround */ \
PIN_SWDIO_OUT_DISABLE(); \
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
\
/* Acknowledge response */ \
SW_READ_BIT(bit); \
ack = bit << 0; \
SW_READ_BIT(bit); \
ack |= bit << 1; \
SW_READ_BIT(bit); \
ack |= bit << 2; \
\
if (ack == DAP_TRANSFER_OK) { /* OK response */ \
/* Data transfer */ \
if (request & DAP_TRANSFER_RnW) { \
/* Read data */ \
val = 0U; \
parity = 0U; \
for (n = 32U; n; n--) { \
SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
parity += bit; \
val >>= 1; \
val |= bit << 31; \
} \
SW_READ_BIT(bit); /* Read Parity */ \
if ((parity ^ bit) & 1U) { \
ack = DAP_TRANSFER_ERROR; \
} \
if (data) { *data = val; } \
/* Turnaround */ \
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
PIN_SWDIO_OUT_ENABLE(); \
} else { \
/* Turnaround */ \
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
PIN_SWDIO_OUT_ENABLE(); \
/* Write data */ \
val = *data; \
parity = 0U; \
for (n = 32U; n; n--) { \
SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
parity += val; \
val >>= 1; \
} \
SW_WRITE_BIT(parity); /* Write Parity Bit */ \
} \
/* Capture Timestamp */ \
if (request & DAP_TRANSFER_TIMESTAMP) { \
DAP_Data.timestamp = TIMESTAMP_GET(); \
} \
/* Idle cycles */ \
n = DAP_Data.transfer.idle_cycles; \
if (n) { \
PIN_SWDIO_OUT(0U); \
for (; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
} \
PIN_SWDIO_OUT(1U); \
return ((uint8_t)ack); \
} \
\
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
/* WAIT or FAULT response */ \
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \
for (n = 32U+1U; n; n--) { \
SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
} \
} \
/* Turnaround */ \
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
SW_CLOCK_CYCLE(); \
} \
PIN_SWDIO_OUT_ENABLE(); \
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
PIN_SWDIO_OUT(0U); \
for (n = 32U+1U; n; n--) { \
SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
} \
} \
PIN_SWDIO_OUT(1U); \
return ((uint8_t)ack); \
} \
\
/* Protocol error */ \
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \
SW_CLOCK_CYCLE(); /* Back off data phase */ \
} \
PIN_SWDIO_OUT_ENABLE(); \
PIN_SWDIO_OUT(1U); \
return ((uint8_t)ack); \
}
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_FAST()
SWD_TransferFunction(Fast)
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
SWD_TransferFunction(Slow)
// SWD Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
uint8_t SWD_Transfer(uint32_t request, uint32_t *data) {
if (DAP_Data.fast_clock) {
return SWD_TransferFast(request, data);
} else {
return SWD_TransferSlow(request, data);
}
}
#endif /* (DAP_SWD != 0) */

File diff suppressed because it is too large Load Diff

2
components/README.md Normal file
View File

@ -0,0 +1,2 @@
# TODO
1. USB

View File

@ -0,0 +1,4 @@
set(COMPONENT_ADD_INCLUDEDIRS ". ../../main")
set(COMPONENT_SRCS "MSOS20Descriptors.c USB_handle.c USBd_config.c")
register_component()

View File

@ -0,0 +1,84 @@
/**
* @file MSOS20Descriptors.c
* @author windowsair
* @brief Store related data of Microsoft OS 2.0 descriptor
* @version 0.1
* @date 2019-11-21
*
* @copyright Copyright (c) 2019
*
*/
////TODO: refactoring into structure
#include <stdint.h>
#include "MSOS20Descriptors.h"
#define USBShort(ui16Value) ((ui16Value) & 0xff), ((ui16Value) >> 8) //((ui16Value) & 0xFF),(((ui16Value) >> 8) & 0xFF)
// Microsoft OS 2.0 descriptor set header
const uint8_t msOs20DescriptorSetHeader[kLengthOfMsOS20] =
{
// Microsoft OS 2.0 Descriptor Set header (Table 10)
0x0A, 0x00, // wLength (Shall be set to 0x0A)
MS_OS_20_SET_HEADER_DESCRIPTOR, 0x00,
0x00, 0x00, 0x03, 0x06, // dwWindowsVersion: Windows 8.1 (NTDDI_WINBLUE)
USBShort(kLengthOfMsOS20), // wTotalLength
// Support WinUSB
// See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/automatic-installation-of-winusb
// Microsoft OS 2.0 compatible ID descriptor (Table 13)
0x14, 0x00, // wLength
USBShort(MS_OS_20_FEATURE_COMPATIBLE_ID), // wDescriptorType
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compatibleID
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleID
// Microsoft OS 2.0 registry property descriptor (Table 14)
0x84, 0x00, // wLength
USBShort(MS_OS_20_FEATURE_REG_PROPERTY),
0x07, 0x00, // wPropertyDataType: REG_MULTI_SZ (Unicode Strings)
0x2A, 0x00, // wPropertyNameLength
'D',0,'e',0,'v',0,'i',0,'c',0,'e',0,'I',0,'n',0,'t',0,'e',0,'r',0,
'f',0,'a',0,'c',0,'e',0,'G',0,'U',0,'I',0,'D',0,'s',0,0,0,
// Set to "DeviceInterfaceGUID" to support WinUSB
0x50, 0x00, // wPropertyDataLength
// WinUSB GUID
'{',0,'C',0,'D',0,'B',0,'3',0,'B',0,'5',0,'A',0,'D',0,'-',0,
'2',0,'9',0,'3',0,'B',0,'-',0,'4',0,'6',0,'6',0,'3',0,'-',0,
'A',0,'A',0,'3',0,'6',0,'-',0,'1',0,'A',0,'A',0,'E',0,'4',0,
'6',0,'4',0,'6',0,'3',0,'7',0,'7',0,'6',0,'}',0,0,0,0,0,
// identify a CMSIS-DAP V2 configuration,
// must set to "{CDB3B5AD-293B-4663-AA36-1AAE46463776}"
};
const uint8_t bosDescriptor[kLengthOfBos] =
{
// Universal Serial Bus 3.0 Specification, Table 9-9.
0x05, // bLength of this descriptor
USB_DESCRIPTOR_TYPE_BOS, // BOS Descriptor type(Constant)
USBShort(kLengthOfBos), // wLength
0x01, // bNumDeviceCaps
// Microsoft OS 2.0 platform capability descriptor header (Table 4)
// See also:
// Universal Serial Bus 3.0 Specification : Format of a Device Capability Descriptor, Table 9-10.
0x1C, // bLength of this first device capability descriptor
// bLength -> The total length of the remaining arrays containing this field
USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, // bDescriptorType
USB_DEVICE_CAPABILITY_TYPE_PLATFORM, // bDevCapabilityType
// Capability-Dependent (See USB3.0 Specification Table 9-10.)
0x00, // bReserved
USB_DEVICE_CAPABILITY_UUID, // MS_OS_20_Platform_Capability_ID
0x00, 0x00, 0x03, 0x06, // dwWindowsVersion: Windows 8.1 (NTDDI_WINBLUE)
USBShort(kLengthOfMsOS20), // wMSOSDescriptorSetTotalLength(length of descriptor set header)
kValueOfbMS_VendorCode, // bMS_VendorCode (0x01 will be ok)
////TODO:change this
0, // bAltEnumCode
};

View File

@ -0,0 +1,81 @@
/**
* @file MSOS20Descriptors.h
* @author windowsair
* @brief
* @version 0.1
* @date 2019-11-21
*
* @copyright Copyright (c) 2019
*
*/
#ifndef __MSOS20DESCRIPTORS_H__
#define __MSOS20DESCRIPTORS_H__
#define kLengthOfMsOS20 0xA2
#define kLengthOfBos 0x21
#define kValueOfbMS_VendorCode 0x01// Just set to 0x01
extern const uint8_t bosDescriptor[kLengthOfBos];
extern const uint8_t msOs20DescriptorSetHeader[kLengthOfMsOS20];
/* Microsoft OS 2.0 Descriptors BEGIN */
// Platform capability BOS descriptor, Table 1.
#define USB_DEVICE_CAPABILITY_TYPE_PLATFORM 5
// Platform capability UUID, Table 3.
// {D8DD60DF-4589-4CC7-9CD2-659D9E648A9F}
#define USB_DEVICE_CAPABILITY_UUID 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F
// Microsoft OS 2.0 descriptor wIndex values enum, Table 8.
#define MS_OS_20_DESCRIPTOR_INDEX 7
#define MS_OS_20_SET_ALT_ENUMERATION 8
// Microsoft OS 2.0 descriptor types enum for wDescriptorType values, Table 9.
#define MS_OS_20_SET_HEADER_DESCRIPTOR 0x00
#define MS_OS_20_SUBSET_HEADER_CONFIGURATION 0x01
#define MS_OS_20_SUBSET_HEADER_FUNCTION 0x02
#define MS_OS_20_FEATURE_COMPATIBLE_ID 0x03
#define MS_OS_20_FEATURE_REG_PROPERTY 0x04
#define MS_OS_20_FEATURE_MIN_RESUME_TIME 0x05
#define MS_OS_20_FEATURE_MODEL_ID 0x06
#define MS_OS_20_FEATURE_CCGP_DEVICE 0x07
/* Microsoft OS 2.0 Descriptors END */
/* Wireless USB Standard Extension Descriptor Types BEGIN */
// Wireless USB Specification 1.1 revison 1.1, Table 7-21.
#define USB_DESCRIPTOR_TYPE_SECURITY 12
#define USB_DESCRIPTOR_TYPE_KEY 13
#define USB_DESCRIPTOR_TYPE_ENCRYPTION_TYPE 14
#define USB_DESCRIPTOR_TYPE_BOS 15
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY 16
#define USB_DESCRIPTOR_TYPE_WIRELESS_ENDPOINT_COMPANION 17
/* Wireless USB Standard Extension Descriptor Types END */
/* Microsoft Extended Compat ID OS Feature Descriptor BEGIN */
#define USB_MS_EXTENDED_COMPAT_ID_VERSION 0x0100
#define USB_MS_EXTENDED_COMPAT_ID_TYPE 0x04
#define USB_COMPATID_NONE {0}
#define USB_SUBCOMPATID_NONE {0}
#define USB_COMPATID_WINUSB "WINUSB\0"
#define USB_COMPATID_RNDIS "RNDIS\0\0"
#define USB_COMPATID_PTP "PTP\0\0\0\0"
#define USB_COMPATID_MTP "MTP\0\0\0\0"
#define USB_COMPATID_BLUETOOTH "BLUTUTH"
#define USB_SUBCOMPATID_BT_V11 "11\0\0\0\0\0"
#define USB_SUBCOMPATID_BT_V12 "12\0\0\0\0\0"
#define USB_SUBCOMPATID_BT_V20EDR "EDR\0\0\0\0"
/* Microsoft Extended Compat ID OS Feature Descriptor END */
#endif

View File

@ -0,0 +1,333 @@
/**
* @file USB_handle.c
* @brief Handle all Standard Device Requests on endpoint 0
* @version 0.1
* @date 2020-01-23
*
* @copyright Copyright (c) 2020
*
*/
#include <stdint.h>
#include <string.h>
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include "USB_handle.h"
#include "USBd_config.h"
#include "usbip_server.h"
#include "usb_defs.h"
#include "MSOS20Descriptors.h"
// const char *strings_list[] = {
// 0, // reserved: available languages
// "windowsair",
// "CMSIS-DAP v2",
// "1234",
// };
const char *strings_list[] = {
0, // reserved: available languages
"windowsair",
"esp8266 CMSIS-DAP",
"1234",
};
// handle functions
static void handleGetDescriptor(usbip_stage2_header *header);
////TODO: may be ok
void handleUSBControlRequest(usbip_stage2_header *header)
{
// Table 9-3. Standard Device Requests
switch (header->u.cmd_submit.request.bmRequestType)
{
case 0x00: // ignore..
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_CLEAR_FEATURE:
os_printf("* CLEAR FEATURE\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_SET_FEATURE:
os_printf("* SET FEATURE\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_SET_ADDRESS:
os_printf("* SET ADDRESS\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_SET_DESCRIPTOR:
os_printf("* SET DESCRIPTOR\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_SET_CONFIGURATION:
os_printf("* SET CONFIGURATION\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
case 0x01: // ignore...
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_CLEAR_FEATURE:
os_printf("* CLEAR FEATURE\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_SET_FEATURE:
os_printf("* SET FEATURE\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_SET_INTERFACE:
os_printf("* SET INTERFACE\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
case 0x02: // ignore..
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_CLEAR_FEATURE:
os_printf("* CLEAR FEATURE\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_SET_FEATURE:
os_printf("* SET INTERFACE\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
case 0x80: // *IMPORTANT*
#if (USE_WINUSB == 0)
case 0x81:
#endif
{
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_GET_CONFIGURATION:
os_printf("* GET CONIFGTRATION\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_GET_DESCRIPTOR:
handleGetDescriptor(header); ////TODO: device_qualifier
break;
case USB_REQ_GET_STATUS:
os_printf("* GET STATUS\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
}
#if (USE_WINUSB == 1)
case 0x81: // ignore...
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_GET_INTERFACE:
os_printf("* GET INTERFACE\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_SET_SYNCH_FRAME:
os_printf("* SET SYNCH FRAME\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
case USB_REQ_GET_STATUS:
os_printf("* GET STATUS\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
#endif
case 0x82: // ignore...
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_GET_STATUS:
os_printf("* GET STATUS\r\n");
send_stage2_submit_data(header, 0, 0, 0);
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
case 0xC0: // Microsoft OS 2.0 vendor-specific descriptor
{
uint16_t *wIndex = (uint16_t *)(&(header->u.cmd_submit.request.wIndex));
switch (*wIndex)
{
case MS_OS_20_DESCRIPTOR_INDEX:
os_printf("* GET MSOS 2.0 vendor-specific descriptor\r\n");
send_stage2_submit_data(header, 0, msOs20DescriptorSetHeader, sizeof(msOs20DescriptorSetHeader));
break;
case MS_OS_20_SET_ALT_ENUMERATION:
// set alternate enumeration command
// bAltEnumCode set to 0
os_printf("Set alternate enumeration.This should not happen.\r\n");
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d,wIndex:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest, *wIndex);
break;
}
break;
}
case 0x21: // Set_Idle for HID
switch (header->u.cmd_submit.request.bRequest)
{
case USB_REQ_SET_IDLE:
os_printf("* SET IDLE\r\n");
send_stage2_submit(header, 0, 0);
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
break;
default:
os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
break;
}
}
static void handleGetDescriptor(usbip_stage2_header *header)
{
// 9.4.3 Get Descriptor
switch (header->u.cmd_submit.request.wValue.u8hi)
{
case USB_DT_DEVICE: // get device descriptor
os_printf("* GET 0x01 DEVICE DESCRIPTOR\r\n");
send_stage2_submit_data(header, 0, &kUSBd0DeviceDescriptor[0], sizeof(kUSBd0DeviceDescriptor));
break;
case USB_DT_CONFIGURATION: // get configuration descriptor
os_printf("* GET 0x02 CONFIGURATION DESCRIPTOR\r\n");
////TODO: ?
if (header->u.cmd_submit.data_length == USB_DT_CONFIGURATION_SIZE)
{
os_printf("Sending only first part of CONFIG\r\n");
send_stage2_submit(header, 0, header->u.cmd_submit.data_length);
send(kSock, kUSBd0ConfigDescriptor, sizeof(kUSBd0ConfigDescriptor), 0);
}
else
{
os_printf("Sending ALL CONFIG\r\n");
send_stage2_submit(header, 0, header->u.cmd_submit.data_length);
send(kSock, kUSBd0ConfigDescriptor, sizeof(kUSBd0ConfigDescriptor), 0);
send(kSock, kUSBd0InterfaceDescriptor, sizeof(kUSBd0InterfaceDescriptor), 0);
}
break;
case USB_DT_STRING:
//os_printf("* GET 0x03 STRING DESCRIPTOR\r\n");
if (header->u.cmd_submit.request.wValue.u8lo == 0)
{
os_printf("** REQUESTED list of supported languages\r\n");
send_stage2_submit_data(header, 0, kLangDescriptor, sizeof(kLangDescriptor));
}
else if (header->u.cmd_submit.request.wValue.u8lo != 0xee)
{
//os_printf("low bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8lo);
//os_printf("high bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8hi);
int slen = strlen(strings_list[header->u.cmd_submit.request.wValue.u8lo]);
int wslen = slen * 2;
int buff_len = sizeof(usb_string_descriptor) + wslen;
char temp_buff[64];
usb_string_descriptor *desc = (usb_string_descriptor *)temp_buff;
desc->bLength = buff_len;
desc->bDescriptorType = USB_DT_STRING;
for (int i = 0; i < slen; i++)
{
desc->wData[i] = strings_list[header->u.cmd_submit.request.wValue.u8lo][i];
}
send_stage2_submit_data(header, 0, (uint8_t *)temp_buff, buff_len);
}
else
{
os_printf("low bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8lo);
os_printf("high bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8hi);
os_printf("***Unsupported String descriptor***\r\n");
}
break;
case USB_DT_INTERFACE:
os_printf("* GET 0x04 INTERFACE DESCRIPTOR (UNIMPLEMENTED)\r\n");
////TODO:UNIMPLEMENTED
send_stage2_submit(header, 0, 0);
break;
case USB_DT_ENDPOINT:
os_printf("* GET 0x05 ENDPOINT DESCRIPTOR (UNIMPLEMENTED)\r\n");
////TODO:UNIMPLEMENTED
send_stage2_submit(header, 0, 0);
break;
case USB_DT_DEVICE_QUALIFIER:
os_printf("* GET 0x06 DEVICE QUALIFIER DESCRIPTOR\r\n");
usb_device_qualifier_descriptor desc;
memset(&desc, 0, sizeof(usb_device_qualifier_descriptor));
send_stage2_submit_data(header, 0, &desc, sizeof(usb_device_qualifier_descriptor));
break;
case USB_DT_OTHER_SPEED_CONFIGURATION:
os_printf("GET 0x07 [UNIMPLEMENTED] USB_DT_OTHER_SPEED_CONFIGURATION\r\n");
////TODO:UNIMPLEMENTED
send_stage2_submit(header, 0, 0);
break;
case USB_DT_INTERFACE_POWER:
os_printf("GET 0x08 [UNIMPLEMENTED] USB_DT_INTERFACE_POWER\r\n");
////TODO:UNIMPLEMENTED
send_stage2_submit(header, 0, 0);
break;
case USB_DT_BOS:
os_printf("* GET 0x0F BOS DESCRIPTOR\r\n");
send_stage2_submit_data(header, 0, bosDescriptor, sizeof(bosDescriptor));
break;
case USB_DT_HID_REPORT:
os_printf("* GET 0x22 HID REPORT DESCRIPTOR\r\n");
send_stage2_submit_data(header, 0, (void *)kHidReportDescriptor, sizeof(kHidReportDescriptor));
break;
default:
os_printf("USB unknown Get Descriptor requested:%d\r\n", header->u.cmd_submit.request.wValue.u8lo);
os_printf("low bit :%d\r\n",header->u.cmd_submit.request.wValue.u8lo);
os_printf("high bit :%d\r\n",header->u.cmd_submit.request.wValue.u8hi);
break;
}
}

View File

@ -0,0 +1,7 @@
#ifndef __USB_HANDLE_H__
#define __USB_HANDLE_H__
#include "usbip_defs.h"
void handleUSBControlRequest(usbip_stage2_header *header);
#endif

View File

@ -0,0 +1,310 @@
////TODO: refactoring into structure
/**
* @file USBd_config.c
* @brief Standard USB Descriptor Definitions
fix bugs 2020-1-23
* @version 0.2
* @date 2020-1-23
*
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "USBd_config.h"
#include "usb_defs.h"
#define USBShort(ui16Value) ((ui16Value) & 0xff), ((ui16Value) >> 8) //((ui16Value) & 0xFF),(((ui16Value) >> 8) & 0xFF)
/**
* @brief step 1. Build Standard Device Descriptor
*
*/
// Standard Device Descriptor
const uint8_t kUSBd0DeviceDescriptor[0x12] =
{
0x12, // bLength
USB_DT_DEVICE, // bDescriptorType
USBShort(0x0210), // bcdUSB
////TODO: Is it also available elsewhere?
// We need to use a device other than the USB-IF standard, set to 0x00
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
USBD0_MAX_PACKET0, // bMaxPacketSize0 Maximum packet size for default pipe.
USBShort(USBD0_DEV_DESC_IDVENDOR), // idVendor Vendor ID (VID).
USBShort(USBD0_DEV_DESC_IDPRODUCT), // idProduct Product ID (PID).
USBShort(USBD0_DEV_DESC_BCDDEVICE), // bcdDevice Device Version BCD.
0x01, // iManufacturer Index of Manufacturer string identifier.
0x02, // iProduct Index of Product string identifier.
0x03 * USBD0_STR_DESC_SER_EN, // iSerialNumber Index of Product serial number.
0x01 // bNumConfigurations Number of configurations.
};
/**
* @brief step 2. Buid Standard Configuration Descriptor
*
*/
// Standard Interface Descriptor
#if (USE_WINUSB ==1)
const uint8_t kUSBd0InterfaceDescriptor[0x1E]=
{
0x09, // bLength
USB_DT_INTERFACE, // bDescriptorType
USBD_CUSTOM_CLASS0_IF0_NUM, // bInterfaceNumber
USBD_CUSTOM_CLASS0_IF0_ALT, // bAlternateSetting
0x03, // bNumEndpoints(we will use 3 endpoints)
//
USBD_CUSTOM_CLASS0_IF0_CLASS, // bInterfaceClass
USBD_CUSTOM_CLASS0_IF0_SUBCLASS, // bInterfaceSubClass
USBD_CUSTOM_CLASS0_IF0_PROTOCOL, // bInterfaceProtocol
0x00, // iInterface
// Index of string descriptor describing this interface
////TODO: fix this 0x04 ?
// Standard Endpoint Descriptor
// Endpoint 1: Bulk Out used for commands received from host PC.
// Endpoint 2: Bulk In used for responses send to host PC.
// Endpoint 3: Bulk In (optional) used for streaming SWO trace
// ATTENTION:
// physical endpoint 1 indeed included two "endpoints": Bulk OUT and Bulk IN
// physical endpoint 1 -> Endpoint 1 & Endpoint 2
// physical endpoint 2 -> Endpoint 3
// See also :
// http://www.keil.com/pack/doc/CMSIS/DAP/html/group__DAP__ConfigUSB__gr.html
/* Pysical endpoint 1 */
// "Endpoint 1: Bulk Out used for commands received from host PC." PC -> Device
0x07, // bLength
USB_DT_ENDPOINT, // bDescriptorType
0x01, // bEndpointAddress
USB_ENDPOINT_ATTR_BULK, // bmAttributes
USBShort(512), // wMaxPacketSize
// We assume that it always runs in High Speed.
0x00, // bInterval
/* Pysical endpoint 1 */
// "Endpoint 2: Bulk In used for responses send to host PC." Device -> PC
0x07, // bLength
USB_DT_ENDPOINT, // bDescriptorType
0x81, // bEndpointAddress
USB_ENDPOINT_ATTR_BULK, // bmAttributes
USBShort(512), // wMaxPacketSize
0x00, // bInterval
/* Pysical endpoint 2 */
// "Endpoint 3: Bulk In (optional) used for streaming SWO trace" Device -> PC
0x07, // bLength
USB_DT_ENDPOINT, // bDescriptorType
0x82, // bEndpointAddress
USB_ENDPOINT_ATTR_BULK, // bmAttributes
USBShort(512), // wMaxPacketSize
0x00, // bInterval
};
#else
const uint8_t kUSBd0InterfaceDescriptor[0x20]=
{
0x09, // bLength
USB_DT_INTERFACE, // bDescriptorType
USBD_CUSTOM_CLASS0_IF0_NUM, // bInterfaceNumber
USBD_CUSTOM_CLASS0_IF0_ALT, // bAlternateSetting
0x02, // bNumEndpoints ----> 2 endpoint for USB HID
//
USBD_CUSTOM_CLASS0_IF0_CLASS, // bInterfaceClass
USBD_CUSTOM_CLASS0_IF0_SUBCLASS, // bInterfaceSubClass
USBD_CUSTOM_CLASS0_IF0_PROTOCOL, // bInterfaceProtocol
0x00, // iInterface
// Index of string descriptor describing this interface
// HID Descriptor
0x09, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
0x00, // bCountryCode
0x01, // bNumDescriptors
0x22, // bDescriptorType1
0x21, 0x00, // wDescriptorLength1
// Standard Endpoint Descriptor
// We perform all transfer operations on Pysical endpoint 1.
/* Pysical endpoint 1 */
0x07, // bLength
USB_DT_ENDPOINT, // bDescriptorType
0x81, // bEndpointAddress
USB_ENDPOINT_ATTR_INTERRUPT, // bmAttributes
USBShort(64), // wMaxPacketSize
0x01, // bInterval
/* Pysical endpoint 1 */
0x07, // bLength
USB_DT_ENDPOINT, // bDescriptorType
0x01, // bEndpointAddress
USB_ENDPOINT_ATTR_INTERRUPT, // bmAttributes
USBShort(64), // wMaxPacketSize
0x01, // bInterval
};
#endif
// Standard Configuration Descriptor
#define LENGTHOFCONFIGDESCRIPTOR 9
#if (USE_WINUSB == 1)
const uint8_t kUSBd0ConfigDescriptor[LENGTHOFCONFIGDESCRIPTOR] =
{
// Configuration descriptor header.
0x09, // bLength
USB_DT_CONFIGURATION, // bDescriptorType
USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (LENGTHOFCONFIGDESCRIPTOR)),
// wTotalLength
0x01, // bNumInterfaces
// There is only one interface in the CMSIS-DAP project
0x01, // bConfigurationValue: 0x01 is used to select this configuration */
0x00, // iConfiguration: no string to describe this configuration */
USBD0_CFG_DESC_BMATTRIBUTES, // bmAttributes
USBD0_CFG_DESC_BMAXPOWER, // bMaxPower
};
#else
const uint8_t kUSBd0ConfigDescriptor[LENGTHOFCONFIGDESCRIPTOR] =
{
// Configuration descriptor header.
0x09, // bLength
USB_DT_CONFIGURATION, // bDescriptorType
USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (LENGTHOFCONFIGDESCRIPTOR)),
// wTotalLength
0x01, // bNumInterfaces
// There is only one interface in the CMSIS-DAP project
0x01, // bConfigurationValue: 0x01 is used to select this configuration */
0x00, // iConfiguration: no string to describe this configuration */
USBD0_CFG_DESC_BMATTRIBUTES, // bmAttributes
USBD0_CFG_DESC_BMAXPOWER, // bMaxPower
};
#endif
// USB HID Report Descriptor
const uint8_t kHidReportDescriptor[0x21] = {
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x01, // Usage (0x01)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0xFF, // Report Count (64)
0x09, 0x01, // Usage (0x01)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0xFF, // Report Count (64)
0x09, 0x01, // Usage (0x01)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01, // Report Count (1)
0x09, 0x01, // Usage (0x01)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
// 33 bytes
};
/**
* @brief step 3. Build String Descriptor
*
*/
const uint8_t kLangDescriptor[0x04] =
{
4,
USB_DT_STRING,
USBShort(USB_LANGID_ENGLISH_US)
};
/**
* @brief We will use these string descriptor:
* 1. Manufacturer string -> "KEIL - Tools By ARM"
* 2. Product string -> "LPC-Link-II"
* 3. Serial number string -> "0001A0000000"
* 4. Interface string -> "LPC-Link-II CMSIS-DAP"
*
*
*/
const uint8_t kManufacturerString[0x28] =
{
0x28, // bLength
0x03, // bDescriptorType
// "KEIL - Tools By ARM"
'K', 0, 'E', 0, 'I', 0, 'L', 0, ' ', 0, '-', 0, ' ', 0, 'T', 0, 'o', 0, 'o', 0,
'l', 0, 's', 0, ' ', 0, 'B', 0, 'y', 0, ' ', 0, 'A', 0, 'R', 0, 'M', 0
};
const uint8_t kProductString[0x18] =
{
0x18, // bLength
0x03, // bDescriptorType
// "LPC-Link-II"
'L', 0, 'P', 0, 'C', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, '-', 0, 'I', 0,
'I', 0
};
const uint8_t kSerialNumberString[0x1A] =
{
0x1A, // bLength
0x03, // bDescriptorType
// "0001A0000000"
'0', 0, '0', 0, '0', 0, '1', 0, 'A', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
'0', 0, '0', 0
};
const uint8_t kInterfaceString[0x2C] =
{
0x2C, // bLength
0x03, // bDescriptorType
// "LPC-Link-II CMSIS-DAP"
'L', 0, 'P', 0, 'C', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, '-', 0, 'I', 0,
'I', 0, ' ', 0, 'C', 0, 'M', 0, 'S', 0, 'I', 0, 'S', 0, '-', 0, 'D', 0, 'A', 0,
'P', 0
};
const uint8_t * const kUSBd0StringDescriptorsSet[0x05] =
{
kLangDescriptor,
kManufacturerString,
kProductString,
kSerialNumberString,
kInterfaceString
};

View File

@ -0,0 +1,66 @@
#ifndef __USBD_CONFIG_H__
#define __USBD_CONFIG_H__
#define USE_WINUSB 0
// Vendor ID assigned by USB-IF (idVendor).
#define USBD0_DEV_DESC_IDVENDOR 0xC251
// Product ID assigned by manufacturer (idProduct).
#define USBD0_DEV_DESC_IDPRODUCT 0xF00A
// Device Release Number in binary-coded decimal (bcdDevice).
#define USBD0_DEV_DESC_BCDDEVICE 0x0100
// Maximum packet size for Endpoint 0 (bMaxPacketSize0).
#define USBD0_MAX_PACKET0 64
// If disabled Serial Number String will not be assigned to USB Device.
#define USBD0_STR_DESC_SER_EN 1
// bmAttributes
#define USBD0_CFG_DESC_BMATTRIBUTES 0x80
// bMaxPower
#define USBD0_CFG_DESC_BMAXPOWER 250
// Interface Number
#define USBD_CUSTOM_CLASS0_IF0_NUM 0
// Alternate Setting
#define USBD_CUSTOM_CLASS0_IF0_ALT 0
// Class Code
#if (USE_WINUSB == 1)
#define USBD_CUSTOM_CLASS0_IF0_CLASS 0xFF // 0xFF: Vendor Specific
#else
#define USBD_CUSTOM_CLASS0_IF0_CLASS 0x03 // 0x03: HID class
#endif
// Subclass Code
#define USBD_CUSTOM_CLASS0_IF0_SUBCLASS 0x00
// Protocol Code
#define USBD_CUSTOM_CLASS0_IF0_PROTOCOL 0x00
/////////////////////////////////////////////
// common part
extern const uint8_t kUSBd0DeviceDescriptor[0x12];
extern const uint8_t kLangDescriptor[0x04];
extern const uint8_t kManufacturerString[0x28];
extern const uint8_t kProductString[0x18];
extern const uint8_t kSerialNumberString[0x1A];
#if (USE_WINUSB == 1)
extern const uint8_t kUSBd0InterfaceDescriptor[0x1E];
extern const uint8_t kUSBd0ConfigDescriptor[0x09];
extern const uint8_t kInterfaceString[0x2C];
#else
extern const uint8_t kUSBd0InterfaceDescriptor[0x20];
extern const uint8_t kUSBd0ConfigDescriptor[0x09];
extern const uint8_t kInterfaceString[0x2C];
extern const uint8_t kHidReportDescriptor[0x21];
#endif
#endif

308
components/USBIP/usb_defs.h Normal file
View File

@ -0,0 +1,308 @@
/**
* @file usb_defs.h
* @brief Modify
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
//
// Created by thevoidnn on 10/25/17.
//
#ifndef __USB_DEFS_H__
#define __USB_DEFS_H__
#include <stdint.h>
#define USB_CLASS_MISCELLANEOUS_DEVICE 0xef
#define USB_MISC_SUBCLASS_COMMON 0x02
#define USB_MISC_PROTOCOL_INTERFACE_ASSOCIATION_DESCRIPTOR 0x01
typedef union {
struct
{
uint8_t u8lo;
uint8_t u8hi;
} __attribute__((packed));
uint16_t u16;
} word_t;
typedef struct
{
uint8_t bmRequestType;
uint8_t bRequest;
word_t wValue; // 16bit
word_t wIndex;
word_t wLength;
} __attribute__((packed)) usb_standard_request;
//#define USB_CLASS_HID 3
#define USB_DT_HID 0x21
#define USB_DT_REPORT 0x22
//struct usb_hid_descriptor {
// uint8_t bLength;
// uint8_t bDescriptorType;
// uint16_t bcdHID;
// uint8_t bCountryCode;
// uint8_t bNumDescriptors;
//} __attribute__((packed));
//#define USB_DT_HID_SIZE sizeof(struct usb_hid_descriptor)
//struct usb_hid_report_descriptor {
// uint8_t bDescriptorType;
// uint16_t wReportLength;
//} __attribute__((packed));
#define USB_DT_REPORT_SIZE sizeof(struct usb_hid_report_descriptor)
/* Class Definition */
#define USB_CLASS_VENDOR 0xFF
///////////////////////////////////////////////////////////////
/* Table 9-2. Format of Setup Data */
/* bmRequestType bit definitions */
/* bit 7 : Direction */
#define USB_REQ_TYPE_OUT 0x00 // Host-to-device
#define USB_REQ_TYPE_IN 0x80 // Device-to-host
/* bits 6..5 : Type */
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
//#define USB_REQ_TYPE_RESERVED 0x60
/* bits 4..0 : Recipient */
#define USB_REQ_TYPE_DEVICE 0x00
#define USB_REQ_TYPE_INTERFACE 0x01
#define USB_REQ_TYPE_ENDPOINT 0x02
#define USB_REQ_TYPE_OTHER 0x03
//#define USB_REQ_TYPE_RESERVED 0x1F
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Standard Request Codes - Table 9-4 */
#define USB_REQ_GET_STATUS 0
#define USB_REQ_CLEAR_FEATURE 1
/* Reserved for future use: 2 */
#define USB_REQ_SET_FEATURE 3
/* Reserved for future use: 3 */
#define USB_REQ_SET_ADDRESS 5
#define USB_REQ_GET_DESCRIPTOR 6
#define USB_REQ_SET_DESCRIPTOR 7
#define USB_REQ_GET_CONFIGURATION 8
#define USB_REQ_SET_CONFIGURATION 9
#define USB_REQ_GET_INTERFACE 10
#define USB_REQ_SET_INTERFACE 11
#define USB_REQ_SET_SYNCH_FRAME 12
// USB HID Request
#define USB_REQ_GET_REPORT 0x01
#define USB_REQ_GET_IDLE 0x02
#define USB_REQ_GET_PROTOCOL 0x03
#define USB_REQ_SET_REPORT 0x09
#define USB_REQ_SET_IDLE 0X0A
#define USB_REQ_SET_PROTOCOL 0X0B
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Descriptor Types - Table 9-5 */
#define USB_DT_DEVICE 1
#define USB_DT_CONFIGURATION 2
#define USB_DT_STRING 3
#define USB_DT_INTERFACE 4
#define USB_DT_ENDPOINT 5
#define USB_DT_DEVICE_QUALIFIER 6
#define USB_DT_OTHER_SPEED_CONFIGURATION 7
#define USB_DT_INTERFACE_POWER 8
#define USB_DT_BOS 15
/* From ECNs */
#define USB_DT_OTG 9
#define USB_DT_DEBUG 10
#define USB_DT_INTERFACE_ASSOCIATION 11
/* USB HID */
#define USB_DT_HID 0x21
#define USB_DT_HID_REPORT 0x22
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Standard Feature Selectors - Table 9-6 */
#define USB_FEAT_ENDPOINT_HALT 0 // Recipient: Device
#define USB_FEAT_DEVICE_REMOTE_WAKEUP 1 // Recipient: Endpoint
#define USB_FEAT_TEST_MODE 2 // Recipient: Device
/* Information Returned by a GetStatus() Request to a Device - Figure 9-4 */
#define USB_DEV_STATUS_SELF_POWERED 0x01
#define USB_DEV_STATUS_REMOTE_WAKEUP 0x02
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Standard Device Descriptor - Table 9-8 */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} __attribute__((packed)) usb_device_descriptor;
#define USB_DT_DEVICE_SIZE sizeof(usb_device_descriptor)
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Device_Qualifier Descriptor - Table 9-9
* Not used in this implementation.
*/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint8_t bNumConfigurations;
uint8_t bReserved;
} __attribute__((packed)) usb_device_qualifier_descriptor;
///////////////////////////////////////////////////////////////
/* This is only defined as a top level named struct to improve c++
* compatibility. You should never need to instance this struct
* in user code! */
typedef struct
{
uint8_t *cur_altsetting;
uint8_t num_altsetting;
const struct usb_iface_assoc_descriptor *iface_assoc;
const struct usb_interface_descriptor *altsetting;
} __attribute__((packed)) usb_interface;
///////////////////////////////////////////////////////////////
/* USB Standard Configuration Descriptor - Table 9-10 */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} __attribute__((packed)) usb_config_descriptor;
#define USB_DT_CONFIGURATION_SIZE sizeof(usb_config_descriptor)
///////////////////////////////////////////////////////////////
/* USB Configuration Descriptor *bmAttributes* bit definitions */
#define USB_CONFIG_ATTR_DEFAULT 0x80 /** always required (USB2.0 table 9-10) */
#define USB_CONFIG_ATTR_SELF_POWERED 0x40
#define USB_CONFIG_ATTR_REMOTE_WAKEUP 0x20
/* Other Speed Configuration is the same as Configuration Descriptor.
* - Table 9-11
*/
///////////////////////////////////////////////////////////////
/* USB Standard Interface Descriptor - Table 9-12 */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} __attribute__((packed)) usb_interface_descriptor;
#define USB_DT_INTERFACE_SIZE sizeof(usb_interface_descriptor)
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* USB Standard Endpoint Descriptor - Table 9-13 */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} __attribute__((packed))usb_endpoint_descriptor;
#define USB_DT_ENDPOINT_SIZE sizeof(usb_endpoint_descriptor)
///////////////////////////////////////////////////////////////
/* USB bEndpointAddress helper macros */
#define USB_ENDPOINT_ADDR_OUT(x) (x)
#define USB_ENDPOINT_ADDR_IN(x) (0x80 | (x))
///////////////////////////////////////////////////////////////
/* USB Endpoint Descriptor bmAttributes bit definitions - Table 9-13 */
/* bits 1..0 : Transfer type */
#define USB_ENDPOINT_ATTR_CONTROL 0x00
#define USB_ENDPOINT_ATTR_ISOCHRONOUS 0x01
#define USB_ENDPOINT_ATTR_BULK 0x02
#define USB_ENDPOINT_ATTR_INTERRUPT 0x03
#define USB_ENDPOINT_ATTR_TYPE 0x03
// If not an isochronous endpoint, bits 5..2 are reserved
// and must be set to zero.
/* bits 3..2 : Sync type (only if ISOCHRONOUS) */
#define USB_ENDPOINT_ATTR_NOSYNC 0x00
#define USB_ENDPOINT_ATTR_ASYNC 0x04
#define USB_ENDPOINT_ATTR_ADAPTIVE 0x08
#define USB_ENDPOINT_ATTR_SYNC 0x0C
#define USB_ENDPOINT_ATTR_SYNCTYPE 0x0C
/* bits 5..4 : Usage type (only if ISOCHRONOUS) */
#define USB_ENDPOINT_ATTR_DATA 0x00
#define USB_ENDPOINT_ATTR_FEEDBACK 0x10
#define USB_ENDPOINT_ATTR_IMPLICIT_FEEDBACK_DATA 0x20
#define USB_ENDPOINT_ATTR_USAGETYPE 0x30
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/* Table 9-15 specifies String Descriptor Zero.
* Table 9-16 specified UNICODE String Descriptor.
*/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wData[];
} __attribute__((packed)) usb_string_descriptor;
/* From ECN: Interface Association Descriptors, Table 9-Z */
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction;
} __attribute__((packed)) usb_iface_assoc_descriptor;
#define USB_DT_INTERFACE_ASSOCIATION_SIZE \
sizeof(usb_iface_assoc_descriptor)
enum usb_language_id
{
USB_LANGID_ENGLISH_US = 0x409,
};
///////////////////////////////////////////////////////////////
#endif

View File

@ -0,0 +1,210 @@
/**
* @file usbip_defs.h
* @brief Simple modification
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
// Focus on the following structures in this file:
// usbip_stage2_header
// usbip_stage1_response_devlist
//
// Created by thevoidnn on 10/25/17.
//
#ifndef __USBIP_DEFS_H__
#define __USBIP_DEFS_H__
#include <stdint.h>
#include "usb_defs.h"
#define USBIP_SYSFS_PATH_SIZE 256
#define USBIP_BUSID_SIZE 32
enum usbip_stage1_command
{
// Offset 2
USBIP_STAGE1_CMD_DEVICE_LIST = 0x05, // OP_REQ_DEVLIST
USBIP_STAGE1_CMD_DEVICE_ATTACH = 0x03, // OP_REQ_IMPORT
};
enum usbip_stager2_command
{
//Offset 0
USBIP_STAGE2_REQ_SUBMIT = 0x0001,
USBIP_STAGE2_REQ_UNLINK = 0x0002,
USBIP_STAGE2_RSP_SUBMIT = 0x0003,
USBIP_STAGE2_RSP_UNLINK = 0x0004,
};
enum usbip_stage2_direction
{
USBIP_DIR_OUT = 0x00,
USBIP_DIR_IN = 0x01,
};
typedef struct
{
uint16_t version;
uint16_t command;
uint32_t status;
} __attribute__((__packed__)) usbip_stage1_header;
/////////////////////////////////////////////////////////////
// Device description
typedef struct
{
char path[USBIP_SYSFS_PATH_SIZE];
char busid[USBIP_BUSID_SIZE];
uint32_t busnum;
uint32_t devnum;
uint32_t speed;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bConfigurationValue;
uint8_t bNumConfigurations;
uint8_t bNumInterfaces;
} __attribute__((packed)) usbip_stage1_usb_device;
// Interface description
typedef struct
{
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t padding;
} __attribute__((packed)) usbip_stage1_usb_interface;
typedef struct
{
usbip_stage1_usb_device udev;
usbip_stage1_usb_interface uinf[];
} __attribute__((packed)) usbip_stage1_response_devlist_entry;
typedef struct
{
uint32_t list_size;
usbip_stage1_response_devlist_entry devices[];
} __attribute__((__packed__)) usbip_stage1_response_devlist;
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/**
* struct usbip_header_basic - data pertinent to every URB request
* RESPONSE & REQUEST
*
* @command: the usbip request type
* @seqnum: sequential number that identifies requests; incremented per
* connection
* @devid: specifies a remote USB device uniquely instead of busnum and devnum;
* in the stub driver, this value is ((busnum << 16) | devnum)
* @direction: direction of the transfer
* @ep: endpoint number
*/
typedef struct
{
uint32_t command;
uint32_t seqnum;
uint32_t devid;
uint32_t direction;
uint32_t ep;
} __attribute__((packed)) usbip_stage2_header_basic;
/**
* struct usbip_header_cmd_submit - USBIP_CMD_SUBMIT packet header
* >>>REQUEST
*
* @transfer_flags: URB flags
* @transfer_buffer_length: the data size for (in) or (out) transfer
* @start_frame: initial frame for isochronous or interrupt transfers
* @number_of_packets: number of isochronous packets
* @interval: maximum time for the request on the server-side host controller
* @setup: setup data for a control request
*/
typedef struct
{
uint32_t transfer_flags;
int32_t data_length;
/* it is difficult for usbip to sync frames (reserved only?) */
int32_t start_frame;
int32_t number_of_packets;
int32_t interval;
union {
uint8_t setup[8];
usb_standard_request request;
};
} __attribute__((packed)) usbip_stage2_header_cmd_submit;
/**
* struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header
* <<<RESPONSE
*
* @status: return status of a non-iso request
* @actual_length: number of bytes transferred
* @start_frame: initial frame for isochronous or interrupt transfers
* @number_of_packets: number of isochronous packets
* @error_count: number of errors for isochronous transfers
*/
typedef struct
{
int32_t status;
int32_t data_length; //actual_length
int32_t start_frame;
int32_t number_of_packets;
int32_t error_count;
} __attribute__((packed)) usbip_stage2_header_ret_submit;
/**
* struct usbip_header_cmd_unlink - USBIP_CMD_UNLINK packet header
* >>>REQUEST
* @seqnum: the URB seqnum to unlink
*/
typedef struct
{
uint32_t seqnum;
} __attribute__((packed)) usbip_stage2_header_cmd_unlink;
/**
* struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header
* <<<RESPONSE
* @status: return status of the request
*/
typedef struct
{
int32_t status;
} __attribute__((packed)) usbip_stage2_header_ret_unlink;
/**
* struct usbip_header - common header for all usbip packets
* @base: the basic header
* @u: packet type dependent header
*/
typedef struct
{
usbip_stage2_header_basic base;
union {
usbip_stage2_header_cmd_submit cmd_submit;
usbip_stage2_header_ret_submit ret_submit;
usbip_stage2_header_cmd_unlink cmd_unlink;
usbip_stage2_header_ret_unlink ret_unlink;
} u;
} __attribute__((packed)) usbip_stage2_header;
#endif

View File

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

215
main/DAP_handle.c Normal file
View File

@ -0,0 +1,215 @@
/**
* @file DAP_handle.c
* @brief Handle DAP packets and transaction push
* @version 0.2
* @date 2020-02-04
*
* @copyright Copyright (c) 2020
*
*/
#include <stdint.h>
#include <string.h>
#include "usbip_server.h"
#include "DAP_handle.h"
#include "DAP.h"
#include "esp_libc.h"
#include "USBd_config.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/ringbuf.h"
#include "freertos/semphr.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
extern int kSock;
extern TaskHandle_t kDAPTaskHandle;
////TODO: Merge this
#define DAP_PACKET_SIZE 255
static uint8_t data_out[DAP_PACKET_SIZE];
static int dap_respond = 0;
// SWO Trace
static int swo_trace_respond = 0;
static uint8_t *swo_data_to_send;
static uint32_t num_swo_data;
static RingbufHandle_t dap_dataIN_handle = NULL;
static RingbufHandle_t dap_dataOUT_handle = NULL;
static SemaphoreHandle_t data_response_mux = NULL;
static void unpack(void *data, int size);
void handle_dap_data_request(usbip_stage2_header *header, uint32_t length)
{
uint8_t *data_in = (uint8_t *)header;
data_in = &(data_in[sizeof(usbip_stage2_header)]);
// Point to the beginning of the URB packet
#if (USE_WINUSB == 1)
dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out);
//handle_dap_data_response(header);
send_stage2_submit(header, 0, 0);
#else
xRingbufferSend(dap_dataIN_handle, data_in, length - sizeof(usbip_stage2_header), portMAX_DELAY);
//os_printf("LENGTH: %d\r\n", length - sizeof(usbip_stage2_header));
xTaskNotifyGive(kDAPTaskHandle);
send_stage2_submit(header, 0, 0);
#endif
}
void handle_dap_data_response(usbip_stage2_header *header)
{
if (dap_respond)
{
send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE);
dap_respond = 0;
}
else
{
send_stage2_submit(header, 0, 0);
}
}
void handle_swo_trace_response(usbip_stage2_header *header)
{
if (swo_trace_respond)
{
swo_trace_respond = 0;
send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE);
}
else
{
send_stage2_submit(header, 0, 0);
}
}
// SWO Data Queue Transfer
// buf: pointer to buffer with data
// num: number of bytes to transfer
void SWO_QueueTransfer(uint8_t *buf, uint32_t num)
{
swo_data_to_send = buf;
num_swo_data = num;
swo_trace_respond = 1;
}
// SWO Data Abort Transfer
void SWO_AbortTransfer(void)
{
//USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
////TODO: unlink might be useful ...
}
void DAP_Thread(void *argument)
{
dap_dataIN_handle = xRingbufferCreate(DAP_PACKET_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
dap_dataOUT_handle = xRingbufferCreate(DAP_PACKET_SIZE * 10, RINGBUF_TYPE_BYTEBUF);
data_response_mux = xSemaphoreCreateMutex();
size_t packetSize;
uint8_t *item;
if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL ||
data_response_mux == NULL)
{
os_printf("Can not create DAP ringbuf/mux!\r\n");
vTaskDelete(NULL);
}
for (;;)
{
while (1)
{
ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
packetSize = 0;
item = (uint8_t *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize,
(1 / portTICK_RATE_MS), DAP_PACKET_SIZE);
if (packetSize == 0)
{
break;
}
else if (packetSize < DAP_PACKET_SIZE)
{
os_printf("Wrong data in packet size:%d , data in remain: %d\r\n", packetSize, (int)xRingbufferGetMaxItemSize(dap_dataIN_handle));
vRingbufferReturnItem(dap_dataIN_handle, (void *)item);
break;
// This may not happen because there is a semaphore acquisition
}
if (item[0] == ID_DAP_QueueCommands)
item[0] = ID_DAP_ExecuteCommands;
DAP_ProcessCommand(item, data_out);
vRingbufferReturnItem(dap_dataIN_handle, (void *)item);
xRingbufferSend(dap_dataOUT_handle, data_out, DAP_PACKET_SIZE, portMAX_DELAY);
if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
{
++dap_respond;
xSemaphoreGive(data_response_mux);
}
}
}
}
int fast_reply(uint8_t *buf, uint32_t length)
{
if (length == 48 && buf[3] == 1 && buf[15] == 1 && buf[19] == 1)
{
if (dap_respond > 0)
{
uint8_t *item;
size_t packetSize = 0;
item = (uint8_t *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize,
(10 / portTICK_RATE_MS), DAP_PACKET_SIZE);
if (packetSize == DAP_PACKET_SIZE)
{
unpack((uint32_t *)buf, sizeof(usbip_stage2_header));
send_stage2_submit_data((usbip_stage2_header *)buf, 0, item, DAP_PACKET_SIZE);
if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
{
--dap_respond;
xSemaphoreGive(data_response_mux);
}
vRingbufferReturnItem(dap_dataOUT_handle, (void *)item);
return 1;
}
else if (packetSize > 0)
{
os_printf("Wrong data out packet size:%d!\r\n", packetSize);
}
////TODO: fast reply
}
else
{
buf[3] = 0x3; // command
buf[15] = 0; // direction
buf[0x16] = 0;
buf[0x17] = 0;
buf[27] = 0;
buf[39] = 0;
send(kSock, buf, 48, 0);
return 1;
}
}
return 0;
}
static void unpack(void *data, int size)
{
// Ignore the setup field
int sz = (size / sizeof(uint32_t)) - 2;
uint32_t *ptr = (uint32_t *)data;
for (int i = 0; i < sz; i++)
{
ptr[i] = ntohl(ptr[i]);
}
}

12
main/DAP_handle.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef __DAP_HANDLE_H__
#define __DAP_HANDLE_H__
#include "usbip_defs.h"
void handle_dap_data_request(usbip_stage2_header *header, uint32_t length);
void handle_dap_data_response(usbip_stage2_header *header);
void handle_swo_trace_response(usbip_stage2_header *header);
int fast_reply(uint8_t *buf, uint32_t length);
#endif

View File

@ -1,37 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
choice EXAMPLE_IP_MODE
prompt "IP Version"
help
Example can use either IPV4 or IPV6.
config EXAMPLE_IPV4
bool "IPV4"
config EXAMPLE_IPV6
bool "IPV6"
select LWIP_IPV6
endchoice
config EXAMPLE_PORT
int "Port"
range 0 65535
default 3333
help
Local port the example server will listen on.
endmenu

View File

@ -1,4 +0,0 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

148
main/main.c Normal file
View File

@ -0,0 +1,148 @@
/* BSD Socket API Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include <stdint.h>
#include <sys/param.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 <lwip/netdb.h>
#include "tcp_server.h"
#include "timer.h"
#include "wifi_configuration.h"
extern void SWO_Thread(void *argument);
extern void usart_monitor_task(void *argument);
extern void DAP_Setup(void);
extern void DAP_Thread(void *argument);
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
TaskHandle_t kDAPTaskHandle = NULL;
const int IPV4_GOTIP_BIT = BIT0;
#ifdef CONFIG_EXAMPLE_IPV6
const int IPV6_GOTIP_BIT = BIT1;
#endif
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch (event->event_id)
{
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
os_printf("SYSTEM_EVENT_STA_START\r\n");
break;
case SYSTEM_EVENT_STA_CONNECTED:
#ifdef CONFIG_EXAMPLE_IPV6
/* enable ipv6 */
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
#endif
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT);
os_printf("SYSTEM_EVENT_STA_GOT_IP\r\n");
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
os_printf("Disconnect reason : %d\r\n", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT)
{
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT);
#ifdef CONFIG_EXAMPLE_IPV6
xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT);
#endif
break;
case SYSTEM_EVENT_AP_STA_GOT_IP6:
#ifdef CONFIG_EXAMPLE_IPV6
xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT);
os_printf("SYSTEM_EVENT_STA_GOT_IP6\r\n");
char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip);
os_printf("IPv6: %s\r\n", ip6);
#endif
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASS,
},
};
os_printf("Setting WiFi configuration SSID %s...\r\n", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
}
static void wait_for_ip()
{
#ifdef CONFIG_EXAMPLE_IPV6
uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT;
#else
uint32_t bits = IPV4_GOTIP_BIT;
#endif
os_printf("Waiting for AP connection...\r\n");
xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY);
os_printf("Connected to AP\r\n");
}
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
wait_for_ip();
DAP_Setup(); // DAP Setup
xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL);
xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 20, NULL);
xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 22, &kDAPTaskHandle);
// SWO Trace Task
//xTaskCreate(SWO_Thread, "swo_task", 1024, NULL, 6, NULL);
//xTaskCreate(usart_monitor_task, "uart_task", 512, NULL, 6, NULL);
}

View File

@ -1,12 +1,16 @@
/* BSD Socket API Example
/**
* @file tcp_server.c
* @brief Handle main tcp tasks
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
#include "tcp_server.h"
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include <stdint.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@ -22,110 +26,15 @@
#include "lwip/sys.h"
#include <lwip/netdb.h>
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID "DAP"
#define EXAMPLE_WIFI_PASS "12345678"
#include "wifi_configuration.h"
#include "usbip_server.h"
#define PORT 22350
uint8_t kState = ACCEPTING;
int kSock = -1;
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
const int IPV4_GOTIP_BIT = BIT0;
#ifdef CONFIG_EXAMPLE_IPV6
const int IPV6_GOTIP_BIT = BIT1;
#endif
static const char *TAG = "example";
static esp_err_t event_handler(void *ctx, system_event_t *event)
void tcp_server_task(void *pvParameters)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch (event->event_id)
{
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
os_printf("SYSTEM_EVENT_STA_START\r\n");
break;
case SYSTEM_EVENT_STA_CONNECTED:
#ifdef CONFIG_EXAMPLE_IPV6
/* enable ipv6 */
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
#endif
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT);
os_printf("SYSTEM_EVENT_STA_GOT_IP\r\n");
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
os_printf("Disconnect reason : %d\r\n", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT)
{
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT);
#ifdef CONFIG_EXAMPLE_IPV6
xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT);
#endif
break;
case SYSTEM_EVENT_AP_STA_GOT_IP6:
#ifdef CONFIG_EXAMPLE_IPV6
xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT);
os_printf("SYSTEM_EVENT_STA_GOT_IP6\r\n");
char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip);
os_printf("IPv6: %s\r\n", ip6);
#endif
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
os_printf("Setting WiFi configuration SSID %s...\r\n", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
}
static void wait_for_ip()
{
#ifdef CONFIG_EXAMPLE_IPV6
uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT;
#else
uint32_t bits = IPV4_GOTIP_BIT;
#endif
os_printf("Waiting for AP connection...\r\n");
xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY);
os_printf("Connected to AP");
}
static void tcp_server_task(void *pvParameters)
{
char rx_buffer[2048];
uint8_t tcp_rx_buffer[305];
char addr_str[128];
int addr_family;
int ip_protocol;
@ -157,7 +66,7 @@ static void tcp_server_task(void *pvParameters)
os_printf("Unable to create socket: errno %d\r\n", errno);
break;
}
os_printf("Socket created");
os_printf("Socket created\r\n");
int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
if (err != 0)
@ -165,7 +74,7 @@ static void tcp_server_task(void *pvParameters)
os_printf("Socket unable to bind: errno %d\r\n", errno);
break;
}
os_printf("Socket binded");
os_printf("Socket binded\r\n");
err = listen(listen_sock, 1);
if (err != 0)
@ -173,86 +82,87 @@ static void tcp_server_task(void *pvParameters)
os_printf("Error occured during listen: errno %d\r\n", errno);
break;
}
os_printf("Socket listening");
os_printf("Socket listening\r\n");
#ifdef CONFIG_EXAMPLE_IPV6
struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6
#else
struct sockaddr_in sourceAddr;
#endif
uint addrLen = sizeof(sourceAddr);
int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
if (sock < 0)
{
os_printf("Unable to accept connection: errno %d\r\n", errno);
break;
}
os_printf("Socket accepted");
uint32_t addrLen = sizeof(sourceAddr);
while (1)
{
int len = recv(sock, rx_buffer, 2047, 0);
// Error occured during receiving
if (len < 0)
kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
if (kSock < 0)
{
os_printf("recv failed: errno %d\r\n", errno);
os_printf("Unable to accept connection: errno %d\r\n", errno);
break;
}
// Connection closed
else if (len == 0)
{
os_printf("Connection closed\r\n");
break;
}
// Data received
else
{
#ifdef CONFIG_EXAMPLE_IPV6
// Get the sender's ip address as string
if (sourceAddr.sin6_family == PF_INET)
{
inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
}
else if (sourceAddr.sin6_family == PF_INET6)
{
inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
}
#else
inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
#endif
os_printf("Socket accepted\r\n");
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
//os_printf("Received %d bytes from %s:\r\n", len, addr_str);
// os_printf("%s", rx_buffer);
int err = send(sock, rx_buffer, len, 0);
if (err < 0)
while (1)
{
int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 0);
// Error occured during receiving
if (len < 0)
{
os_printf("Error occured during sending: errno %d\r\n", errno);
os_printf("recv failed: errno %d\r\n", errno);
break;
}
// Connection closed
else if (len == 0)
{
os_printf("Connection closed\r\n");
break;
}
// Data received
else
{
// #ifdef CONFIG_EXAMPLE_IPV6
// // Get the sender's ip address as string
// if (sourceAddr.sin6_family == PF_INET)
// {
// inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
// }
// else if (sourceAddr.sin6_family == PF_INET6)
// {
// inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
// }
// #else
// inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
// #endif
switch (kState)
{
case ACCEPTING:
kState = ATTACHING;
case ATTACHING:
attach(tcp_rx_buffer, len);
break;
case EMULATING:
emulate(tcp_rx_buffer, len);
break;
default:
os_printf("unkonw kstate!\r\n");
}
}
}
}
// kState = ACCEPTING;
if (kSock != -1)
{
os_printf("Shutting down socket and restarting...\r\n");
//shutdown(kSock, 0);
close(kSock);
if (kState == EMULATING)
kState = ACCEPTING;
if (sock != -1)
{
os_printf("Shutting down socket and restarting...\r\n");
shutdown(sock, 0);
close(sock);
shutdown(listen_sock, 0);
close(listen_sock);
vTaskDelay(5);
//shutdown(listen_sock, 0);
//close(listen_sock);
//vTaskDelay(5);
}
}
}
vTaskDelete(NULL);
}
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
wait_for_ip();
xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL);
}
}

6
main/tcp_server.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __TCP_SERVER_H__
#define __TCP_SERVER_H__
void tcp_server_task(void *pvParameters);
#endif

29
main/timer.c Normal file
View File

@ -0,0 +1,29 @@
/**
* @file timer.c
* @brief Hardware timer for DAP timestamp
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "timer.h"
#include "hw_timer.h"
#include "timer_struct.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
void timer_create_task()
{
// FRC1 frequency 80MHz
vPortEnterCritical();
frc1.ctrl.div = TIMER_CLKDIV_16; // 80MHz / 16 = 5MHz
frc1.ctrl.intr_type = TIMER_EDGE_INT;
frc1.ctrl.reload = 0x01;
frc1.load.data = 0x7FFFFF; // 23bit??
frc1.ctrl.en = 0x01;
vPortExitCritical();
vTaskDelete(NULL);
}

6
main/timer.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __TIMER_H__
#define __TIMER_H__
void timer_create_task();
#endif

376
main/usbip_server.c Normal file
View File

@ -0,0 +1,376 @@
#include <stdint.h>
#include <string.h>
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include "usbip_server.h"
#include "usbip_defs.h"
#include "usb_defs.h"
#include "USBd_config.h"
#include "DAP_handle.h"
#include "USB_handle.h"
#include "USBd_config.h"
// attach helper function
static int read_stage1_command(uint8_t *buffer, uint32_t length);
static void handle_device_list(uint8_t *buffer, uint32_t length);
static void handle_device_attach(uint8_t *buffer, uint32_t length);
static void send_stage1_header(uint16_t command, uint32_t status);
static void send_device_list();
static void send_device_info();
static void send_interface_info();
// emulate helper function
static void pack(void *data, int size);
static void unpack(void *data, int size);
static int handle_submit(usbip_stage2_header *header, uint32_t length);
static int read_stage2_command(usbip_stage2_header *header, uint32_t length);
static void handle_unlink(usbip_stage2_header *header);
// unlink helper function
static void send_stage2_unlink(usbip_stage2_header *req_header);
int attach(uint8_t *buffer, uint32_t length)
{
int command = read_stage1_command(buffer, length);
if (command < 0)
{
return -1;
}
switch (command)
{
case USBIP_STAGE1_CMD_DEVICE_LIST: // OP_REQ_DEVLIST
handle_device_list(buffer, length);
break;
case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT
handle_device_attach(buffer, length);
break;
default:
os_printf("attach Unknown command: %d\r\n", command);
break;
}
return 0;
}
static int read_stage1_command(uint8_t *buffer, uint32_t length)
{
if (length < sizeof(usbip_stage1_header))
{
return -1;
}
usbip_stage1_header *req = (usbip_stage1_header *)buffer;
return (ntohs(req->command) & 0xFF); // 0x80xx low bit
}
static void handle_device_list(uint8_t *buffer, uint32_t length)
{
os_printf("Handling dev list request...\r\n");
send_stage1_header(USBIP_STAGE1_CMD_DEVICE_LIST, 0);
send_device_list();
}
static void handle_device_attach(uint8_t *buffer, uint32_t length)
{
os_printf("Handling dev attach request...\r\n");
//char bus[USBIP_BUSID_SIZE];
if (length < sizeof(USBIP_BUSID_SIZE))
{
os_printf("handle device attach failed!\r\n");
return;
}
//client.readBytes((uint8_t *)bus, USBIP_BUSID_SIZE);
send_stage1_header(USBIP_STAGE1_CMD_DEVICE_ATTACH, 0);
send_device_info();
kState = EMULATING;
}
static void send_stage1_header(uint16_t command, uint32_t status)
{
os_printf("Sending header...\r\n");
usbip_stage1_header header;
header.version = htons(273); ////TODO: 273???
// may be : https://github.com/Oxalin/usbip_windows/issues/4
header.command = htons(command);
header.status = htonl(status);
send(kSock, (uint8_t *)&header, sizeof(usbip_stage1_header), 0);
}
static void send_device_list()
{
os_printf("Sending device list...\r\n");
// send device list size:
os_printf("Sending device list size...\r\n");
usbip_stage1_response_devlist response_devlist;
// we have only 1 device, so:
response_devlist.list_size = htonl(1);
send(kSock, (uint8_t *)&response_devlist, sizeof(usbip_stage1_response_devlist), 0);
// may be foreach:
{
// send device info:
send_device_info();
// send device interfaces: // (1)
send_interface_info();
}
}
static void send_device_info()
{
os_printf("Sending device info...\r\n");
usbip_stage1_usb_device device;
strcpy(device.path, "/sys/devices/pci0000:00/0000:00:01.2/usb1/1-1");
strcpy(device.busid, "1-1");
device.busnum = htonl(1);
device.devnum = htonl(1);
device.speed = htonl(3); // See usb_device_speed enum
device.idVendor = htons(USBD0_DEV_DESC_IDVENDOR);
device.idProduct = htons(USBD0_DEV_DESC_IDPRODUCT);
device.bcdDevice = htons(USBD0_DEV_DESC_BCDDEVICE);
device.bDeviceClass = 0x00; // We need to use a device other than the USB-IF standard, set to 0x00
device.bDeviceSubClass = 0x00;
device.bDeviceProtocol = 0x00;
device.bConfigurationValue = 1;
device.bNumConfigurations = 1;
device.bNumInterfaces = 1;
send(kSock, (uint8_t *)&device, sizeof(usbip_stage1_usb_device), 0);
}
static void send_interface_info()
{
os_printf("Sending interface info...\r\n");
usbip_stage1_usb_interface interface;
interface.bInterfaceClass = USBD_CUSTOM_CLASS0_IF0_CLASS;
interface.bInterfaceSubClass = USBD_CUSTOM_CLASS0_IF0_SUBCLASS;
interface.bInterfaceProtocol = USBD_CUSTOM_CLASS0_IF0_PROTOCOL;
interface.padding = 0; // shall be set to zero
send(kSock, (uint8_t *)&interface, sizeof(usbip_stage1_usb_interface), 0);
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
int emulate(uint8_t *buffer, uint32_t length)
{
// usbip_stage2_header header;
#if (USE_WINUSB == 0)
if(fast_reply(buffer, length))
{
return 0;
}
#endif
int command = read_stage2_command((usbip_stage2_header *)buffer, length);
if (command < 0)
{
return -1;
}
switch (command)
{
case USBIP_STAGE2_REQ_SUBMIT:
handle_submit((usbip_stage2_header *)buffer , length);
break;
case USBIP_STAGE2_REQ_UNLINK:
handle_unlink((usbip_stage2_header *)buffer);
break;
default:
os_printf("emulate unknown command:%d\r\n", command);
//handle_submit((usbip_stage2_header *)buffer, length);
return -1;
}
return 0;
}
static int read_stage2_command(usbip_stage2_header *header, uint32_t length)
{
if (length < sizeof(usbip_stage2_header))
{
return -1;
}
//client.readBytes((uint8_t *)&header, sizeof(usbip_stage2_header));
unpack((uint32_t *)header, sizeof(usbip_stage2_header));
return header->base.command;
}
/**
* @brief Pack the following packets(Offset 0x00 - 0x28):
* - cmd_submit
* - ret_submit
* - cmd_unlink
* - ret_unlink
*
* @param data Point to packets header
* @param size Packets header size
*/
static void pack(void *data, int size)
{
// Ignore the setup field
int sz = (size / sizeof(uint32_t)) - 2;
uint32_t *ptr = (uint32_t *)data;
for (int i = 0; i < sz; i++)
{
ptr[i] = htonl(ptr[i]);
}
}
/**
* @brief Unack the following packets(Offset 0x00 - 0x28):
* - cmd_submit
* - ret_submit
* - cmd_unlink
* - ret_unlink
*
* @param data Point to packets header
* @param size packets header size
*/
static void unpack(void *data, int size)
{
// Ignore the setup field
int sz = (size / sizeof(uint32_t)) - 2;
uint32_t *ptr = (uint32_t *)data;
for (int i = 0; i < sz; i++)
{
ptr[i] = ntohl(ptr[i]);
}
}
/**
* @brief USB transaction processing
*
*/
static int handle_submit(usbip_stage2_header *header, uint32_t length)
{
switch (header->base.ep)
{
// control endpoint(endpoint 0)
case 0x00:
handleUSBControlRequest(header);
break;
// endpoint 1 data receicve and response
case 0x01:
if (header->base.direction == 0)
{
//os_printf("EP 01 DATA FROM HOST");
handle_dap_data_request(header ,length);
}
else
{
// os_printf("EP 01 DATA TO HOST\r\n");
handle_dap_data_response(header);
}
break;
// endpoint 2 for SWO trace
case 0x02:
if (header->base.direction == 0)
{
// os_printf("EP 02 DATA FROM HOST");
send_stage2_submit(header, 0, 0);
}
else
{
// os_printf("EP 02 DATA TO HOST");
handle_swo_trace_response(header);
}
break;
// request to save data to device
case 0x81:
if (header->base.direction == 0)
{
os_printf("*** WARN! EP 81 DATA TX");
}
else
{
os_printf("*** WARN! EP 81 DATA RX");
}
return -1;
default:
os_printf("*** WARN ! UNKNOWN ENDPOINT: %d\r\n", (int)header->base.ep);
return -1;
}
return 0;
}
void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length)
{
req_header->base.command = USBIP_STAGE2_RSP_SUBMIT;
req_header->base.direction = !(req_header->base.direction);
memset(&(req_header->u.ret_submit), 0, sizeof(usbip_stage2_header_ret_submit));
req_header->u.ret_submit.status = status;
req_header->u.ret_submit.data_length = data_length;
pack(req_header, sizeof(usbip_stage2_header));
send(kSock, req_header, sizeof(usbip_stage2_header), 0);
}
void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, const void *const data, int32_t data_length)
{
send_stage2_submit(req_header, status, data_length);
if (data_length)
{
send(kSock, data, data_length, 0);
}
}
static void handle_unlink(usbip_stage2_header *header)
{
os_printf("s2 handling cmd unlink...\r\n");
send_stage2_unlink(header);
}
static void send_stage2_unlink(usbip_stage2_header *req_header)
{
req_header->base.command = USBIP_STAGE2_RSP_UNLINK;
req_header->base.direction = USBIP_DIR_OUT;
memset(&(req_header->u.ret_unlink), 0, sizeof(usbip_stage2_header_ret_unlink));
// req_header.u.ret_unlink.status = 0;
pack(req_header, sizeof(usbip_stage2_header));
send(kSock, req_header, sizeof(usbip_stage2_header), 0);
}

19
main/usbip_server.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef __USBIP_SERVER_H__
#define __USBIP_SERVER_H__
#include <stdint.h>
#include "usbip_defs.h"
enum state_t
{
ACCEPTING,
ATTACHING,
EMULATING
};
extern uint8_t kState;
extern int kSock;
int attach(uint8_t *buffer, uint32_t length);
int emulate(uint8_t *buffer, uint32_t length);
void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, const void * const data, int32_t data_length);
void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length);
#endif

20
main/wifi_configuration.h Normal file
View File

@ -0,0 +1,20 @@
/**
* @file wifi_configuration.h
* @brief Fill in your wifi configuration information here.
* @version 0.1
* @date 2020-01-22
*
* @copyright Copyright (c) 2020
*
*/
#ifndef __WIFI_CONFIGURATION__
#define __WIFI_CONFIGURATION__
#define WIFI_SSID "DAP"
#define WIFI_PASS "12345678"
#define PORT 3240
#define CONFIG_EXAMPLE_IPV4 1
#endif

View File

@ -33,19 +33,19 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
CONFIG_ESPTOOLPY_FLASHMODE="dio"
CONFIG_SPI_FLASH_MODE=0x0
# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set
CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set
# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
CONFIG_SPI_FLASH_FREQ=0x0
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
CONFIG_SPI_FLASH_FREQ=0xf
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE="8MB"
CONFIG_SPI_FLASH_SIZE=0x800000
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
CONFIG_ESPTOOLPY_FLASHSIZE="16MB"
CONFIG_SPI_FLASH_SIZE=0x1000000
CONFIG_ESPTOOLPY_BEFORE_RESET=y
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
CONFIG_ESPTOOLPY_BEFORE="default_reset"
@ -69,16 +69,11 @@ CONFIG_PARTITION_TABLE_SINGLE_APP=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0x8000
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
CONFIG_WIFI_SSID="myssid"
CONFIG_WIFI_PASSWORD="mypassword"
CONFIG_EXAMPLE_IPV4=y
# CONFIG_EXAMPLE_IPV6 is not set
CONFIG_EXAMPLE_PORT=3333
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE is not set
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
@ -87,7 +82,7 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
# CONFIG_COMPILER_STACK_CHECK is not set
# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
CONFIG_APP_UPDATE_CHECK_APP_SUM=y
# CONFIG_APP_UPDATE_CHECK_APP_HASH is not set
CONFIG_APP_UPDATE_CHECK_APP_HASH=y
# CONFIG_AWS_IOT_SDK is not set
# CONFIG_USING_ESP_CONSOLE is not set
CONFIG_ESP_TLS_USING_MBEDTLS=y
@ -107,8 +102,8 @@ CONFIG_ESP_FILENAME_MACRO_NO_PATH=y
# CONFIG_ESP_FILENAME_MACRO_NULL is not set
CONFIG_USING_NEW_ETS_VPRINTF=y
# CONFIG_LINK_ETS_PRINTF_TO_IRAM is not set
# CONFIG_SOC_FULL_ICACHE is not set
CONFIG_SOC_IRAM_SIZE=0xC000
CONFIG_SOC_FULL_ICACHE=y
CONFIG_SOC_IRAM_SIZE=0x8000
CONFIG_CONSOLE_UART_DEFAULT=y
# CONFIG_CONSOLE_UART_CUSTOM is not set
# CONFIG_CONSOLE_UART_NONE is not set
@ -130,7 +125,6 @@ CONFIG_TASK_WDT_TIMEOUT_S=15
CONFIG_RESET_REASON=y
CONFIG_WIFI_PPT_TASKSTACK_SIZE=2048
CONFIG_EVENT_LOOP_STACK_SIZE=2048
CONFIG_ESP8266_CORE_GLOBAL_DATA_LINK_IRAM=y
# CONFIG_ESP8266_OTA_FROM_OLD is not set
# CONFIG_ESP8266_BOOT_COPY_APP is not set
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
@ -141,7 +135,7 @@ CONFIG_WIFI_TX_RATE_SEQUENCE_FROM_HIGH=y
# CONFIG_ESP8266_WIFI_QOS_ENABLED is not set
# CONFIG_ESP8266_WIFI_AMPDU_RX_ENABLED is not set
# CONFIG_ESP8266_WIFI_AMSDU_ENABLED is not set
CONFIG_ESP8266_WIFI_RX_BUFFER_NUM=16
CONFIG_ESP8266_WIFI_RX_BUFFER_NUM=26
CONFIG_ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM=4
CONFIG_ESP8266_WIFI_RX_PKT_NUM=7
CONFIG_ESP8266_WIFI_TX_PKT_NUM=6
@ -151,8 +145,8 @@ CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET=y
CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y
# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set
CONFIG_ESP_PHY_INIT_DATA_VDD33_CONST=33
CONFIG_ESP8266_PHY_MAX_WIFI_TX_POWER=20
# CONFIG_ESP8266_HSPI_HIGH_THROUGHPUT is not set
CONFIG_ESP8266_PHY_MAX_WIFI_TX_POWER=21
CONFIG_ESP8266_HSPI_HIGH_THROUGHPUT=y
CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
CONFIG_HTTP_BUF_SIZE=512
CONFIG_HTTPD_MAX_REQ_HDR_LEN=512
@ -166,33 +160,31 @@ CONFIG_FREERTOS_MAX_HOOK=2
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024
CONFIG_FREERTOS_ISR_STACKSIZE=512
# CONFIG_FREERTOS_EXTENED_HOOKS is not set
CONFIG_FREERTOS_GLOBAL_DATA_LINK_IRAM=y
# CONFIG_FREERTOS_CODE_LINK_TO_IRAM is not set
CONFIG_FREERTOS_CODE_LINK_TO_IRAM=y
CONFIG_FREERTOS_TIMER_STACKSIZE=2048
CONFIG_TASK_SWITCH_FASTER=y
# CONFIG_USE_QUEUE_SETS is not set
# CONFIG_ENABLE_FREERTOS_SLEEP is not set
# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
# CONFIG_HEAP_DISABLE_IRAM is not set
CONFIG_HEAP_DISABLE_IRAM=y
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set
# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
CONFIG_LOG_DEFAULT_LEVEL=3
CONFIG_LOG_DEFAULT_LEVEL=1
CONFIG_LOG_COLORS=y
# CONFIG_LOG_SET_LEVEL is not set
# CONFIG_LWIP_USE_IRAM is not set
# CONFIG_LWIP_HIGH_THROUGHPUT is not set
CONFIG_LWIP_GLOBAL_DATA_LINK_IRAM=y
CONFIG_TCPIP_RECVMBOX_SIZE=32
CONFIG_LWIP_USE_IRAM=y
CONFIG_LWIP_HIGH_THROUGHPUT=y
CONFIG_TCPIP_RECVMBOX_SIZE=64
CONFIG_LWIP_ARP_TABLE_SIZE=10
CONFIG_LWIP_ARP_MAXAGE=300
# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set
CONFIG_LWIP_SOCKET_MULTITHREAD=y
# CONFIG_ENABLE_NONBLOCK_SPEEDUP is not set
CONFIG_ENABLE_NONBLOCK_SPEEDUP=y
CONFIG_SET_SOLINGER_DEFAULT=y
CONFIG_ESP_UDP_SYNC_SEND=y
CONFIG_ESP_UDP_SYNC_RETRY_MAX=5
@ -202,8 +194,8 @@ CONFIG_LWIP_SO_REUSE_RXTOALL=y
# CONFIG_LWIP_SO_RCVBUF is not set
CONFIG_LWIP_RECV_BUFSIZE_DEFAULT=11680
CONFIG_LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT=10000
# CONFIG_LWIP_IP_FRAG is not set
# CONFIG_LWIP_IP_REASSEMBLY is not set
CONFIG_LWIP_IP_FRAG=y
CONFIG_LWIP_IP_REASSEMBLY=y
CONFIG_LWIP_IP_REASS_MAX_PBUFS=10
# CONFIG_LWIP_IP_SOF_BROADCAST is not set
# CONFIG_LWIP_IP_SOF_BROADCAST_RECV is not set
@ -221,7 +213,7 @@ CONFIG_LWIP_IGMP=y
CONFIG_ESP_DNS=y
CONFIG_DNS_MAX_SERVERS=3
# CONFIG_LWIP_NETIF_LOOPBACK is not set
# CONFIG_TCP_HIGH_SPEED_RETRANSMISSION is not set
CONFIG_TCP_HIGH_SPEED_RETRANSMISSION=y
CONFIG_LWIP_MAX_ACTIVE_TCP=5
CONFIG_LWIP_MAX_LISTENING_TCP=8
CONFIG_TCP_MAXRTX=12
@ -229,7 +221,7 @@ CONFIG_TCP_SYNMAXRTX=6
CONFIG_TCP_MSS=1460
CONFIG_TCP_SND_BUF_DEFAULT=2920
CONFIG_TCP_WND_DEFAULT=5840
CONFIG_TCP_RECVMBOX_SIZE=6
CONFIG_TCP_RECVMBOX_SIZE=16
CONFIG_TCP_QUEUE_OOSEQ=y
CONFIG_TCP_OVERSIZE_MSS=y
# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set
@ -237,7 +229,7 @@ CONFIG_TCP_OVERSIZE_MSS=y
# CONFIG_LWIP_TCP_TIMESTAMPS is not set
CONFIG_LWIP_MAX_UDP_PCBS=4
CONFIG_UDP_RECVMBOX_SIZE=6
CONFIG_TCPIP_TASK_STACK_SIZE=2048
CONFIG_TCPIP_TASK_STACK_SIZE=4096
CONFIG_LWIP_MAX_RAW_PCBS=4
# CONFIG_LWIP_IPV6 is not set
# CONFIG_LWIP_STATS is not set
@ -343,7 +335,6 @@ CONFIG_OPENSSL_ASSERT_DO_NOTHING=y
# CONFIG_ENABLE_PTHREAD is not set
# CONFIG_USING_SPIFFS is not set
CONFIG_IP_LOST_TIMER_INTERVAL=120
CONFIG_TCPIP_ADAPTER_GLOBAL_DATA_LINK_IRAM=y
# CONFIG_util_assert is not set
CONFIG_ESP_SHA=y
CONFIG_ESP_AES=y
@ -372,9 +363,9 @@ CONFIG_MONITOR_BAUD_OTHER_VAL=74880
CONFIG_MONITOR_BAUD=74880
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
# CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED is not set
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED=y
# CONFIG_CXX_EXCEPTIONS is not set
CONFIG_STACK_CHECK_NONE=y
# CONFIG_STACK_CHECK_NORM is not set