Merge branch 'feature/tcp' into develop
This commit is contained in:
commit
fa620583bb
|
@ -1 +1,2 @@
|
|||
.vscode/
|
||||
build/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# Attention
|
||||
|
||||
At present, the adaptation to WCID, WinUSB, etc. has all been completed. However, when transmitting data on the endpoint, we received an error message from USBIP. This is most likely a problem with the USBIP project itself.
|
||||
|
||||
Due to the completeness of the USBIP protocol document, we have not yet understood its role in the Bulk transmission process, which may also lead to errors in subsequent processes.
|
||||
|
||||
We will continue to try to make it work under USB HID. Once the USBIP problem is solved, we will immediately transfer it to work under WinUSB
|
|
@ -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()
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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_
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
}
|
||||
|
||||
///@}
|
|
@ -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) */
|
|
@ -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)) */
|
|
@ -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
|
@ -0,0 +1,2 @@
|
|||
# TODO
|
||||
1. USB
|
|
@ -0,0 +1,4 @@
|
|||
set(COMPONENT_ADD_INCLUDEDIRS ". ../../main")
|
||||
set(COMPONENT_SRCS "MSOS20Descriptors.c USB_handle.c USBd_config.c")
|
||||
|
||||
register_component()
|
|
@ -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
|
||||
};
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __USB_HANDLE_H__
|
||||
#define __USB_HANDLE_H__
|
||||
|
||||
#include "usbip_defs.h"
|
||||
void handleUSBControlRequest(usbip_stage2_header *header);
|
||||
|
||||
#endif
|
|
@ -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
|
||||
};
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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()
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -1,4 +0,0 @@
|
|||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
|
@ -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 = 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\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);
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef __TCP_SERVER_H__
|
||||
#define __TCP_SERVER_H__
|
||||
|
||||
void tcp_server_task(void *pvParameters);
|
||||
|
||||
#endif
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef __TIMER_H__
|
||||
#define __TIMER_H__
|
||||
|
||||
void timer_create_task();
|
||||
|
||||
#endif
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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 EXAMPLE_WIFI_SSID "DAP"
|
||||
#define EXAMPLE_WIFI_PASS "12345678"
|
||||
|
||||
#define PORT 3240
|
||||
|
||||
#define CONFIG_EXAMPLE_IPV4 1
|
||||
|
||||
#endif
|
73
sdkconfig
73
sdkconfig
|
@ -33,19 +33,19 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
|||
# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
|
||||
CONFIG_ESPTOOLPY_FLASHMODE="dio"
|
||||
CONFIG_SPI_FLASH_MODE=0x0
|
||||
# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set
|
||||
# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
|
||||
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
|
||||
CONFIG_SPI_FLASH_FREQ=0x0
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
||||
CONFIG_SPI_FLASH_FREQ=0xf
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="8MB"
|
||||
CONFIG_SPI_FLASH_SIZE=0x800000
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="16MB"
|
||||
CONFIG_SPI_FLASH_SIZE=0x1000000
|
||||
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
||||
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
||||
CONFIG_ESPTOOLPY_BEFORE="default_reset"
|
||||
|
@ -69,16 +69,11 @@ CONFIG_PARTITION_TABLE_SINGLE_APP=y
|
|||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
|
||||
CONFIG_WIFI_SSID="myssid"
|
||||
CONFIG_WIFI_PASSWORD="mypassword"
|
||||
CONFIG_EXAMPLE_IPV4=y
|
||||
# CONFIG_EXAMPLE_IPV6 is not set
|
||||
CONFIG_EXAMPLE_PORT=3333
|
||||
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
||||
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE is not set
|
||||
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
||||
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
|
||||
# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
|
||||
CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
|
||||
# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
|
||||
|
@ -87,7 +82,7 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
|
|||
# CONFIG_COMPILER_STACK_CHECK is not set
|
||||
# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
|
||||
CONFIG_APP_UPDATE_CHECK_APP_SUM=y
|
||||
# CONFIG_APP_UPDATE_CHECK_APP_HASH is not set
|
||||
CONFIG_APP_UPDATE_CHECK_APP_HASH=y
|
||||
# CONFIG_AWS_IOT_SDK is not set
|
||||
# CONFIG_USING_ESP_CONSOLE is not set
|
||||
CONFIG_ESP_TLS_USING_MBEDTLS=y
|
||||
|
@ -107,8 +102,8 @@ CONFIG_ESP_FILENAME_MACRO_NO_PATH=y
|
|||
# CONFIG_ESP_FILENAME_MACRO_NULL is not set
|
||||
CONFIG_USING_NEW_ETS_VPRINTF=y
|
||||
# CONFIG_LINK_ETS_PRINTF_TO_IRAM is not set
|
||||
# CONFIG_SOC_FULL_ICACHE is not set
|
||||
CONFIG_SOC_IRAM_SIZE=0xC000
|
||||
CONFIG_SOC_FULL_ICACHE=y
|
||||
CONFIG_SOC_IRAM_SIZE=0x8000
|
||||
CONFIG_CONSOLE_UART_DEFAULT=y
|
||||
# CONFIG_CONSOLE_UART_CUSTOM is not set
|
||||
# CONFIG_CONSOLE_UART_NONE is not set
|
||||
|
@ -130,7 +125,6 @@ CONFIG_TASK_WDT_TIMEOUT_S=15
|
|||
CONFIG_RESET_REASON=y
|
||||
CONFIG_WIFI_PPT_TASKSTACK_SIZE=2048
|
||||
CONFIG_EVENT_LOOP_STACK_SIZE=2048
|
||||
CONFIG_ESP8266_CORE_GLOBAL_DATA_LINK_IRAM=y
|
||||
# CONFIG_ESP8266_OTA_FROM_OLD is not set
|
||||
# CONFIG_ESP8266_BOOT_COPY_APP is not set
|
||||
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
|
||||
|
@ -141,7 +135,7 @@ CONFIG_WIFI_TX_RATE_SEQUENCE_FROM_HIGH=y
|
|||
# CONFIG_ESP8266_WIFI_QOS_ENABLED is not set
|
||||
# CONFIG_ESP8266_WIFI_AMPDU_RX_ENABLED is not set
|
||||
# CONFIG_ESP8266_WIFI_AMSDU_ENABLED is not set
|
||||
CONFIG_ESP8266_WIFI_RX_BUFFER_NUM=16
|
||||
CONFIG_ESP8266_WIFI_RX_BUFFER_NUM=26
|
||||
CONFIG_ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM=4
|
||||
CONFIG_ESP8266_WIFI_RX_PKT_NUM=7
|
||||
CONFIG_ESP8266_WIFI_TX_PKT_NUM=6
|
||||
|
@ -151,8 +145,8 @@ CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET=y
|
|||
CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y
|
||||
# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set
|
||||
CONFIG_ESP_PHY_INIT_DATA_VDD33_CONST=33
|
||||
CONFIG_ESP8266_PHY_MAX_WIFI_TX_POWER=20
|
||||
# CONFIG_ESP8266_HSPI_HIGH_THROUGHPUT is not set
|
||||
CONFIG_ESP8266_PHY_MAX_WIFI_TX_POWER=21
|
||||
CONFIG_ESP8266_HSPI_HIGH_THROUGHPUT=y
|
||||
CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
|
||||
CONFIG_HTTP_BUF_SIZE=512
|
||||
CONFIG_HTTPD_MAX_REQ_HDR_LEN=512
|
||||
|
@ -166,33 +160,31 @@ CONFIG_FREERTOS_MAX_HOOK=2
|
|||
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024
|
||||
CONFIG_FREERTOS_ISR_STACKSIZE=512
|
||||
# CONFIG_FREERTOS_EXTENED_HOOKS is not set
|
||||
CONFIG_FREERTOS_GLOBAL_DATA_LINK_IRAM=y
|
||||
# CONFIG_FREERTOS_CODE_LINK_TO_IRAM is not set
|
||||
CONFIG_FREERTOS_CODE_LINK_TO_IRAM=y
|
||||
CONFIG_FREERTOS_TIMER_STACKSIZE=2048
|
||||
CONFIG_TASK_SWITCH_FASTER=y
|
||||
# CONFIG_USE_QUEUE_SETS is not set
|
||||
# CONFIG_ENABLE_FREERTOS_SLEEP is not set
|
||||
# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
|
||||
# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
|
||||
# CONFIG_HEAP_DISABLE_IRAM is not set
|
||||
CONFIG_HEAP_DISABLE_IRAM=y
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
|
||||
CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
|
||||
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
|
||||
CONFIG_LOG_DEFAULT_LEVEL=3
|
||||
CONFIG_LOG_DEFAULT_LEVEL=1
|
||||
CONFIG_LOG_COLORS=y
|
||||
# CONFIG_LOG_SET_LEVEL is not set
|
||||
# CONFIG_LWIP_USE_IRAM is not set
|
||||
# CONFIG_LWIP_HIGH_THROUGHPUT is not set
|
||||
CONFIG_LWIP_GLOBAL_DATA_LINK_IRAM=y
|
||||
CONFIG_TCPIP_RECVMBOX_SIZE=32
|
||||
CONFIG_LWIP_USE_IRAM=y
|
||||
CONFIG_LWIP_HIGH_THROUGHPUT=y
|
||||
CONFIG_TCPIP_RECVMBOX_SIZE=64
|
||||
CONFIG_LWIP_ARP_TABLE_SIZE=10
|
||||
CONFIG_LWIP_ARP_MAXAGE=300
|
||||
# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set
|
||||
CONFIG_LWIP_SOCKET_MULTITHREAD=y
|
||||
# CONFIG_ENABLE_NONBLOCK_SPEEDUP is not set
|
||||
CONFIG_ENABLE_NONBLOCK_SPEEDUP=y
|
||||
CONFIG_SET_SOLINGER_DEFAULT=y
|
||||
CONFIG_ESP_UDP_SYNC_SEND=y
|
||||
CONFIG_ESP_UDP_SYNC_RETRY_MAX=5
|
||||
|
@ -202,8 +194,8 @@ CONFIG_LWIP_SO_REUSE_RXTOALL=y
|
|||
# CONFIG_LWIP_SO_RCVBUF is not set
|
||||
CONFIG_LWIP_RECV_BUFSIZE_DEFAULT=11680
|
||||
CONFIG_LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT=10000
|
||||
# CONFIG_LWIP_IP_FRAG is not set
|
||||
# CONFIG_LWIP_IP_REASSEMBLY is not set
|
||||
CONFIG_LWIP_IP_FRAG=y
|
||||
CONFIG_LWIP_IP_REASSEMBLY=y
|
||||
CONFIG_LWIP_IP_REASS_MAX_PBUFS=10
|
||||
# CONFIG_LWIP_IP_SOF_BROADCAST is not set
|
||||
# CONFIG_LWIP_IP_SOF_BROADCAST_RECV is not set
|
||||
|
@ -221,7 +213,7 @@ CONFIG_LWIP_IGMP=y
|
|||
CONFIG_ESP_DNS=y
|
||||
CONFIG_DNS_MAX_SERVERS=3
|
||||
# CONFIG_LWIP_NETIF_LOOPBACK is not set
|
||||
# CONFIG_TCP_HIGH_SPEED_RETRANSMISSION is not set
|
||||
CONFIG_TCP_HIGH_SPEED_RETRANSMISSION=y
|
||||
CONFIG_LWIP_MAX_ACTIVE_TCP=5
|
||||
CONFIG_LWIP_MAX_LISTENING_TCP=8
|
||||
CONFIG_TCP_MAXRTX=12
|
||||
|
@ -229,7 +221,7 @@ CONFIG_TCP_SYNMAXRTX=6
|
|||
CONFIG_TCP_MSS=1460
|
||||
CONFIG_TCP_SND_BUF_DEFAULT=2920
|
||||
CONFIG_TCP_WND_DEFAULT=5840
|
||||
CONFIG_TCP_RECVMBOX_SIZE=6
|
||||
CONFIG_TCP_RECVMBOX_SIZE=16
|
||||
CONFIG_TCP_QUEUE_OOSEQ=y
|
||||
CONFIG_TCP_OVERSIZE_MSS=y
|
||||
# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set
|
||||
|
@ -237,7 +229,7 @@ CONFIG_TCP_OVERSIZE_MSS=y
|
|||
# CONFIG_LWIP_TCP_TIMESTAMPS is not set
|
||||
CONFIG_LWIP_MAX_UDP_PCBS=4
|
||||
CONFIG_UDP_RECVMBOX_SIZE=6
|
||||
CONFIG_TCPIP_TASK_STACK_SIZE=2048
|
||||
CONFIG_TCPIP_TASK_STACK_SIZE=4096
|
||||
CONFIG_LWIP_MAX_RAW_PCBS=4
|
||||
# CONFIG_LWIP_IPV6 is not set
|
||||
# CONFIG_LWIP_STATS is not set
|
||||
|
@ -343,7 +335,6 @@ CONFIG_OPENSSL_ASSERT_DO_NOTHING=y
|
|||
# CONFIG_ENABLE_PTHREAD is not set
|
||||
# CONFIG_USING_SPIFFS is not set
|
||||
CONFIG_IP_LOST_TIMER_INTERVAL=120
|
||||
CONFIG_TCPIP_ADAPTER_GLOBAL_DATA_LINK_IRAM=y
|
||||
# CONFIG_util_assert is not set
|
||||
CONFIG_ESP_SHA=y
|
||||
CONFIG_ESP_AES=y
|
||||
|
@ -372,9 +363,9 @@ CONFIG_MONITOR_BAUD_OTHER_VAL=74880
|
|||
CONFIG_MONITOR_BAUD=74880
|
||||
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||
CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
|
||||
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
|
||||
# CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED is not set
|
||||
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
||||
# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
|
||||
CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED=y
|
||||
# CONFIG_CXX_EXCEPTIONS is not set
|
||||
CONFIG_STACK_CHECK_NONE=y
|
||||
# CONFIG_STACK_CHECK_NORM is not set
|
||||
|
|
Loading…
Reference in New Issue