0
0
Fork 0

Merge branch 'release/winusb-V0.1'

This commit is contained in:
windowsair 2020-12-27 20:37:47 +08:00
commit a150d05e9b
21 changed files with 1337 additions and 793 deletions

1
.gitignore vendored
View File

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

View File

@ -3,5 +3,7 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
#set(COMPONENT_DIRS "${IDF_PATH}/components ${PROJECT_PATH}/components") #set(COMPONENT_DIRS "${IDF_PATH}/components ${PROJECT_PATH}/components")
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp8266_dap) project(esp8266_dap)

View File

@ -1,8 +1,8 @@
<p align="center"><img src="https://user-images.githubusercontent.com/17078589/73821108-300bda00-482e-11ea-89f6-011a50037a12.png"/></p> <p align="center"><img src="https://user-images.githubusercontent.com/17078589/73821108-300bda00-482e-11ea-89f6-011a50037a12.png"/></p>
<h1 align="center">Wireless ESP8266 DAP</h1> <h1 align="center">Wireless ESP8266 DAP</h1>
[![Build Status](https://travis-ci.com/windowsair/wireless-esp8266-dap.svg?branch=master)](https://travis-ci.com/windowsair/wireless-esp8266-dap) master [![Build Status](https://github.com/windowsair/wireless-esp8266-dap/workflows/build/badge.svg?branch=master)](https://github.com/windowsair/wireless-esp8266-dap/actions?query=branch%3Amaster) master
[![Build Status](https://travis-ci.com/windowsair/wireless-esp8266-dap.svg?branch=develop)](https://travis-ci.com/windowsair/wireless-esp8266-dap) develop [![Build Status](https://github.com/windowsair/wireless-esp8266-dap/workflows/build/badge.svg?branch=develop)](https://github.com/windowsair/wireless-esp8266-dap/actions?query=branch%3Adevelop) develop
[![](https://img.shields.io/badge/license-MIT-green.svg?style=flat-square)](https://github.com/windowsair/wireless-esp8266-dap/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg?style=flat-square)](https://github.com/windowsair/wireless-esp8266-dap/pulls) [![%e2%9d%a4](https://img.shields.io/badge/made%20with-%e2%9d%a4-ff69b4.svg?style=flat-square)](https://github.com/windowsair/wireless-esp8266-dap) [![](https://img.shields.io/badge/license-MIT-green.svg?style=flat-square)](https://github.com/windowsair/wireless-esp8266-dap/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg?style=flat-square)](https://github.com/windowsair/wireless-esp8266-dap/pulls) [![%e2%9d%a4](https://img.shields.io/badge/made%20with-%e2%9d%a4-ff69b4.svg?style=flat-square)](https://github.com/windowsair/wireless-esp8266-dap)
@ -32,8 +32,9 @@ Realized by USBIP and CMSIS-DAP protocol stack.
- [ ] SWO Streaming Trace - [ ] SWO Streaming Trace
4. More.. 4. More..
- [x] Custom maximum debug clock ~~(more than 10MHz)~~ (experimental) - [x] Custom maximum debug clock (40MHz, SWD only)
- [ ] ... - [x] SWD protocol based on SPI acceleration
- [x] ...
@ -82,6 +83,14 @@ You can modify these pin definitions in [DAP_config.h](components/DAP/config/DAP
## Build ## Build
You can build locally or use Github Action to build online
### Build with Github Action Online
See: [Build with Github Action](https://github.com/windowsair/wireless-esp8266-dap/wiki/Build-with-Github-Action)
### General build
1. Get ESP8266 RTOS Software Development Kit 1. Get ESP8266 RTOS Software Development Kit
For now, use the 3.3-rc1 version of the SDK (this is a known issue) For now, use the 3.3-rc1 version of the SDK (this is a known issue)
@ -117,14 +126,14 @@ python ./idf.py -p /dev/ttyS5 flash
3. Connect it with usbip: 3. Connect it with usbip:
```bash ```bash
# HID Mode # HID Mode only
# for pre-compiled version on SourceForge # for pre-compiled version on SourceForge
# or usbip old version # or usbip old version
.\usbip.exe -D -a <your-esp8266-ip-address> 1-1 .\usbip.exe -D -a <your-esp8266-ip-address> 1-1
# HID Mode Or WinUSB Mode # HID Mode Or WinUSB Mode
# for usbip-win 0.3.0 kmdf ude # for usbip-win 0.3.0 kmdf ude
.\usbip.exe attach-ude -r <your-esp8266-ip-address> -b 1-1 .\usbip.exe attach_ude -r <your-esp8266-ip-address> -b 1-1
``` ```
@ -141,6 +150,8 @@ Then test it under MDK:
## Develop ## Develop
0. Check other branches to know the latest development progress.
1. Use WinUSB Mode: 1. Use WinUSB Mode:
change `USE_WINUSB` macor in [USBd_config.h](components/USBIP/USBd_config.h) change `USE_WINUSB` macor in [USBd_config.h](components/USBIP/USBd_config.h)
@ -153,16 +164,20 @@ Then test it under MDK:
> - https://github.com/cezanne/usbip-win for usbip windows > - https://github.com/cezanne/usbip-win for usbip windows
In this repo you can find the complete implementation of the USB protocol stack including USB-HID, WCID, WinUSB. Although WinUSB-based mode currently does not work on USBIP :disappointed_relieved: . They are very easy and can help you quickly build your own DAP on other hardware platforms. In this repo you can find the complete implementation of the USB protocol stack including USB-HID, WCID, WinUSB. ~~Although WinUSB-based mode currently does not work on USBIP~~ :disappointed_relieved: . They are very easy and can help you quickly build your own DAP on other hardware platforms.
Currently using USB-HID for transmission is still slightly slower, If you have any ideas, welcome: Currently TCP transmission speed needs to be further improved, If you have any ideas, welcome:
- [New issues](https://github.com/windowsair/wireless-esp8266-dap/issues) - [New issues](https://github.com/windowsair/wireless-esp8266-dap/issues)
- [New pull](https://github.com/windowsair/wireless-esp8266-dap/pulls) - [New pull](https://github.com/windowsair/wireless-esp8266-dap/pulls)
### Issue ### Issue
2020.12.1
TCP transmission speed needs to be further improved.
2020.11.11 2020.11.11
Winusb is now available, but it is very slow. Winusb is now available, but it is very slow.

View File

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

View File

@ -36,6 +36,8 @@
#include "timer_struct.h" #include "timer_struct.h"
#include "esp8266/pin_mux_register.h" #include "esp8266/pin_mux_register.h"
#include "spi_switch.h"
#include "dap_configuration.h"
//************************************************************************************************** //**************************************************************************************************
/** /**
\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information \defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information
@ -64,7 +66,7 @@ This information includes:
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz
// This value is used to replace the largest 10MHZ speed clock in Keil // 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. #define MAX_USER_CLOCK 16000000 ///< Specifies the max Debug Clock in Hz.
/// Number of processor cycles for I/O Port write operations. /// 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 /// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O
@ -96,18 +98,11 @@ This information includes:
#define DAP_DEFAULT_SWJ_CLOCK 1000000U ///< Default SWD/JTAG clock frequency in Hz. #define DAP_DEFAULT_SWJ_CLOCK 1000000U ///< Default SWD/JTAG clock frequency in Hz.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<1MHz // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<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. /// Maximum Package Buffers for Command and Response data.
/// This configuration settings is used to optimize the communication performance with the /// 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 /// 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). /// setting can be reduced (valid range is 1 .. 255).
#define DAP_PACKET_COUNT 20 ///< Specifies number of packets buffered. #define DAP_PACKET_COUNT 255 ///< Specifies number of packets buffered.
/// Indicate that UART Serial Wire Output (SWO) trace is available. /// 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>. /// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
@ -189,12 +184,13 @@ __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str)
// Modify your pins here // Modify your pins here
// ATTENTION: DO NOT USE RTC GPIO16 // ATTENTION: DO NOT USE RTC GPIO16
#define PIN_SWDIO 4 #define PIN_SWDIO 12
#define PIN_SWCLK 5 #define PIN_SWDIO_MOSI 13 // SPI MOSI
#define PIN_TDO 13 #define PIN_SWCLK 14
#define PIN_TDI 12 #define PIN_TDO 4
#define PIN_TDI 0
#define PIN_nTRST 0 // optional #define PIN_nTRST 0 // optional
#define PIN_nRESET 14 #define PIN_nRESET 5
// LED_BUILTIN // LED_BUILTIN
#define PIN_LED_CONNECTED 2 #define PIN_LED_CONNECTED 2
// LED_BUILTIN // LED_BUILTIN
@ -300,18 +296,25 @@ __STATIC_INLINE void PORT_SWD_SETUP(void)
{ {
gpio_pin_reg_t pin_reg; gpio_pin_reg_t pin_reg;
// gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT);
// gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT); // PIN_SWCLK -> OUTPUT
GPIO.enable_w1ts |= (0x1 << PIN_SWCLK); // PIN_SWDIO -> OUTPUT
GPIO.pin[PIN_SWCLK].driver = 0; // GPIO.enable_w1ts |= (0x1 << PIN_SWCLK);
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWCLK)); // GPIO.pin[PIN_SWCLK].driver = 0;
pin_reg.pullup = 0; // pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWCLK));
WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWCLK), pin_reg.val); // pin_reg.pullup = 0;
GPIO.enable_w1ts |= (0x1 << PIN_SWDIO); // WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWCLK), pin_reg.val);
GPIO.pin[PIN_SWDIO].driver = 0; // GPIO.enable_w1ts |= (0x1 << PIN_SWDIO);
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWDIO)); // GPIO.pin[PIN_SWDIO].driver = 0;
pin_reg.pullup = 0; // pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWDIO));
WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWDIO), pin_reg.val); // pin_reg.pullup = 0;
// WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWDIO), pin_reg.val);
DAP_SPI_Disable();
GPIO.out_w1tc |= (0x1 << PIN_SWCLK);
GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI);
// gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT); // gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
GPIO.enable_w1tc |= (0x1 << PIN_TDO); GPIO.enable_w1tc |= (0x1 << PIN_TDO);
@ -360,11 +363,18 @@ __STATIC_INLINE void PORT_OFF(void)
// gpio_set_direction(PIN_nTRST, GPIO_MODE_DEF_DISABLE); // gpio_set_direction(PIN_nTRST, GPIO_MODE_DEF_DISABLE);
// gpio_set_direction(PIN_nRESET, GPIO_MODE_DEF_DISABLE); // gpio_set_direction(PIN_nRESET, GPIO_MODE_DEF_DISABLE);
GPIO.pin[PIN_SWCLK].driver = 0; // GPIO.pin[PIN_SWCLK].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_SWCLK); // GPIO.enable_w1tc |= (0x1 << PIN_SWCLK);
// GPIO.pin[PIN_SWDIO].driver = 0;
// GPIO.enable_w1tc |= (0x1 << PIN_SWDIO);
// GPIO.pin[PIN_SWDIO].driver = 0;
// GPIO.enable_w1tc |= (0x1 << PIN_SWDIO_MOSI);
DAP_SPI_Disable();
GPIO.out_w1tc |= (0x1 << PIN_SWCLK);
GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI);
GPIO.pin[PIN_SWDIO].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_SWDIO);
GPIO.pin[PIN_TDO].driver = 0; GPIO.pin[PIN_TDO].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_TDO); GPIO.enable_w1tc |= (0x1 << PIN_TDO);
@ -431,7 +441,7 @@ __STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void)
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void) __STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void)
{ {
GPIO.out_w1ts |= (0x1 << PIN_SWDIO); GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI);
} }
/** /**
@ -441,7 +451,7 @@ __STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void)
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void) __STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void)
{ {
GPIO.out_w1tc |= (0x1 << PIN_SWDIO); GPIO.out_w1tc |= (0x1 << PIN_SWDIO_MOSI);
} }
/** /**
@ -470,13 +480,13 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit)
if ((bit & 1U) == 1) if ((bit & 1U) == 1)
{ {
//set bit //set bit
GPIO.out_w1ts |= (0x1 << PIN_SWDIO); GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI);
} }
else else
{ {
//reset bit //reset bit
GPIO.out_w1tc |= (0x1 << PIN_SWDIO); GPIO.out_w1tc |= (0x1 << PIN_SWDIO_MOSI);
} }
} }
@ -489,10 +499,12 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit)
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void) __STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void)
{ {
// Need fast response // Need fast response
//// TODO: low speed
// set \ref gpio_set_direction -> OUTPUT // set \ref gpio_set_direction -> OUTPUT
GPIO.enable_w1ts |= (0x1 << PIN_SWDIO); // GPIO.enable_w1ts |= (0x1 << PIN_SWDIO_MOSI);
GPIO.pin[PIN_SWDIO].driver = 0; // GPIO.pin[PIN_SWDIO_MOSI].driver = 0;
do {}while (0);
} }
/** /**
@ -505,8 +517,9 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void)
// Need fast response // Need fast response
// set \ref gpio_set_dircetion -> INPUT // set \ref gpio_set_dircetion -> INPUT
// esp8266 input is always connected // esp8266 input is always connected
GPIO.enable_w1tc |= (0x1 << PIN_SWDIO); // GPIO.enable_w1tc |= (0x1 << PIN_SWDIO_MOSI);
GPIO.pin[PIN_SWDIO].driver = 0; // GPIO.pin[PIN_SWDIO_MOSI].driver = 0;
GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI);
} }
// TDI Pin I/O --------------------------------------------- // TDI Pin I/O ---------------------------------------------
@ -576,17 +589,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void)
*/ */
__STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) __STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit)
{ {
// ////TODO: What does this mean? ? ? // Vendor reset sequence
// if ((bit & 1U) == 1)
// {
// //set bit
// GPIO.out_w1ts |= (0x1 << PIN_nTRST);
// }
// else
// {
// //reset bit
// GPIO.out_w1tc |= (0x1 << PIN_nTRST);
// }
; // not available ; // not available
} }
@ -611,7 +614,8 @@ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void)
*/ */
__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) __STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit)
{ {
////TODO: What does this mean? ? ? // Vendor reset sequence
//// FIXME: unavailable
if ((bit & 1U) == 1) if ((bit & 1U) == 1)
{ {
//set bit //set bit
@ -733,9 +737,13 @@ Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled an
*/ */
__STATIC_INLINE void DAP_SETUP(void) __STATIC_INLINE void DAP_SETUP(void)
{ {
DAP_SPI_Init();
DAP_SPI_Disable();
// This function maybe unnecessary... // This function maybe unnecessary...
gpio_set_direction(PIN_SWCLK, GPIO_MODE_DEF_INPUT); // gpio_set_direction(PIN_SWCLK, GPIO_MODE_DEF_INPUT);
gpio_set_direction(PIN_SWDIO, 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_nRESET, GPIO_MODE_DEF_INPUT); //
gpio_set_direction(PIN_TDI, GPIO_MODE_DEF_INPUT); gpio_set_direction(PIN_TDI, GPIO_MODE_DEF_INPUT);
gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT); gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
@ -745,6 +753,8 @@ __STATIC_INLINE void DAP_SETUP(void)
LED_CONNECTED_OUT(0); LED_CONNECTED_OUT(0);
gpio_set_direction(PIN_LED_RUNNING, GPIO_MODE_DEF_OUTPUT); gpio_set_direction(PIN_LED_RUNNING, GPIO_MODE_DEF_OUTPUT);
LED_RUNNING_OUT(0); LED_RUNNING_OUT(0);
PORT_OFF();
} }
/** Reset Target Device with custom specific I/O pin or command sequence. /** Reset Target Device with custom specific I/O pin or command sequence.

View File

@ -7,6 +7,9 @@
#ifndef __STATIC_INLINE #ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline __attribute__((always_inline)) #define __STATIC_INLINE static inline __attribute__((always_inline))
#endif #endif
#ifndef __FORCEINLINE
#define __FORCEINLINE inline __attribute__((always_inline))
#endif
#ifndef __WEAK #ifndef __WEAK
#define __WEAK __attribute__((weak)) #define __WEAK __attribute__((weak))
#endif #endif

View File

@ -0,0 +1,33 @@
#ifndef __DAP_UTILITY_H__
#define __DAP_UTILITY_H__
#include <stdint.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
extern const uint8_t kParityByteTable[256];
__STATIC_FORCEINLINE uint8_t ParityEvenUint32(uint32_t v)
{
v ^= v >> 16;
v ^= v >> 8;
v ^= v >> 4;
v &= 0xf;
return (0x6996 >> v) & 1;
}
__STATIC_FORCEINLINE uint8_t ParityEvenUint8(uint8_t v)
{
return kParityByteTable[v];
}
#endif

View File

@ -0,0 +1,19 @@
#ifndef __SPI_OP_H__
#define __SPI_OP_H__
#include <stdint.h>
void DAP_SPI_WriteBits(const uint8_t count, const uint8_t *buf);
void DAP_SPI_Send_Header(const uint8_t packetHeaderData, uint8_t *ack, uint8_t TrnAfterACK);
void DAP_SPI_Read_Data(uint32_t* resData, uint8_t* resParity);
void DAP_SPI_Write_Data(uint32_t data, uint8_t parity);
void DAP_SPI_Generate_Cycle(uint8_t num);
void DAP_SPI_Protocol_Error_Read();
void DAP_SPI_Protocol_Error_Write();
#endif

View File

@ -0,0 +1,10 @@
#ifndef __SPI_SWITCH_H__
#define __SPI_SWITCH_H__
void DAP_SPI_Init();
void DAP_SPI_Deinit();
void DAP_SPI_Enable();
void DAP_SPI_Disable();
#endif

View File

@ -28,6 +28,12 @@
#include "DAP_config.h" #include "DAP_config.h"
#include "DAP.h" #include "DAP.h"
#include "spi_op.h"
#include "spi_switch.h"
#include "dap_utility.h"
// Debug
#define PRINT_SWD_PROTOCOL 0
// SW Macros // SW Macros
@ -54,7 +60,8 @@
PIN_SWCLK_SET(); \ PIN_SWCLK_SET(); \
PIN_DELAY() PIN_DELAY()
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) //#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
#define PIN_DELAY() PIN_DELAY_FAST()
// Generate SWJ Sequence // Generate SWJ Sequence
@ -63,25 +70,13 @@
// return: none // return: none
#if ((DAP_SWD != 0) || (DAP_JTAG != 0)) #if ((DAP_SWD != 0) || (DAP_JTAG != 0))
void SWJ_Sequence (uint32_t count, const uint8_t *data) { void SWJ_Sequence (uint32_t count, const uint8_t *data) {
uint32_t val; if (count != 8 && count != 16 && count!= 51)
uint32_t n; {
printf("[ERROR] wrong SWJ Swquence length:%d\r\n", (int)count);
val = 0U; return;
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--;
} }
DAP_SPI_Enable();
DAP_SPI_WriteBits(count, data);
} }
#endif #endif
@ -133,131 +128,176 @@ void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) {
// request: A[3:2] RnW APnDP // request: A[3:2] RnW APnDP
// data: DATA[31:0] // data: DATA[31:0]
// return: ACK[2:0] // return: ACK[2:0]
#define SWD_TransferFunction(speed) /**/ \
//// TODO: low speed
#define SWD_TransferFunction(speed) /* Speed may be useless, because all use this function */ \
static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \ static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
uint32_t ack; \ SWD_Transfer_Common(request,data); \
uint32_t bit; \ return 1; \
uint32_t val; \ }
uint32_t parity; \
\ static uint8_t SWD_Transfer_Common (uint32_t request, uint32_t *data) {
uint32_t n; \ uint8_t ack;
\ // uint32_t bit;
/* Packet Request */ \ uint32_t val;
parity = 0U; \ uint8_t parity;
SW_WRITE_BIT(1U); /* Start Bit */ \ uint8_t computedParity;
bit = request >> 0; \
SW_WRITE_BIT(bit); /* APnDP Bit */ \ uint32_t n;
parity += bit; \
bit = request >> 1; \ int retryCount = 0;
SW_WRITE_BIT(bit); /* RnW Bit */ \ const uint8_t constantBits = 0b10000001U; /* Start Bit & Stop Bit & Park Bit is fixed. */
parity += bit; \ uint8_t requestByte; /* LSB */
bit = request >> 2; \
SW_WRITE_BIT(bit); /* A2 Bit */ \
parity += bit; \ DAP_SPI_Enable();
bit = request >> 3; \ do {
SW_WRITE_BIT(bit); /* A3 Bit */ \ requestByte = constantBits | (((uint8_t)(request & 0xFU)) << 1U) | (ParityEvenUint8(request & 0xFU) << 5U);
parity += bit; \ /* For 4bit, Parity can be equivalent to 8bit with all 0 high bits */
SW_WRITE_BIT(parity); /* Parity Bit */ \
SW_WRITE_BIT(0U); /* Stop Bit */ \ #if (PRINT_SWD_PROTOCOL == 1)
SW_WRITE_BIT(1U); /* Park Bit */ \ switch (requestByte)
\ {
/* Turnaround */ \ case 0xA5U:
PIN_SWDIO_OUT_DISABLE(); \ printf("IDCODE\r\n");
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ break;
SW_CLOCK_CYCLE(); \ case 0xA9U:
} \ printf("W CTRL/STAT\r\n");
\ break;
/* Acknowledge response */ \ case 0xBDU:
SW_READ_BIT(bit); \ printf("RDBUFF\r\n");
ack = bit << 0; \ break;
SW_READ_BIT(bit); \ case 0x8DU:
ack |= bit << 1; \ printf("R CTRL/STAT\r\n");
SW_READ_BIT(bit); \ break;
ack |= bit << 2; \ case 0x81U:
\ printf("W ABORT\r\n");
if (ack == DAP_TRANSFER_OK) { /* OK response */ \ break;
/* Data transfer */ \ case 0xB1U:
if (request & DAP_TRANSFER_RnW) { \ printf("W SELECT\r\n");
/* Read data */ \ break;
val = 0U; \ case 0xBBU:
parity = 0U; \ printf("W APc\r\n");
for (n = 32U; n; n--) { \ break;
SW_READ_BIT(bit); /* Read RDATA[0:31] */ \ case 0x9FU:
parity += bit; \ printf("R APc\r\n");
val >>= 1; \ break;
val |= bit << 31; \ case 0x8BU:
} \ printf("W AP4\r\n");
SW_READ_BIT(bit); /* Read Parity */ \ break;
if ((parity ^ bit) & 1U) { \ case 0xA3U:
ack = DAP_TRANSFER_ERROR; \ printf("W AP0\r\n");
} \ break;
if (data) { *data = val; } \ case 0X87U:
/* Turnaround */ \ printf("R AP0\r\n");
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ break;
SW_CLOCK_CYCLE(); \ case 0xB7U:
} \ printf("R AP8\r\n");
PIN_SWDIO_OUT_ENABLE(); \ break;
} else { \ default:
/* Turnaround */ \ //W AP8
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ printf("Unknown:%08x\r\n", requestByte);
SW_CLOCK_CYCLE(); \ break;
} \ }
PIN_SWDIO_OUT_ENABLE(); \ #endif
/* Write data */ \
val = *data; \
parity = 0U; \
for (n = 32U; n; n--) { \ if (request & DAP_TRANSFER_RnW) {
SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \ /* Read data */
parity += val; \
val >>= 1; \ DAP_SPI_Send_Header(requestByte, &ack, 0); // 0 Trn After ACK
} \ if (ack == DAP_TRANSFER_OK) {
SW_WRITE_BIT(parity); /* Write Parity Bit */ \ DAP_SPI_Read_Data(&val, &parity);
} \ computedParity = ParityEvenUint32(val);
/* Capture Timestamp */ \
if (request & DAP_TRANSFER_TIMESTAMP) { \ if ((computedParity ^ parity) & 1U) {
DAP_Data.timestamp = TIMESTAMP_GET(); \ ack = DAP_TRANSFER_ERROR;
} \ }
/* Idle cycles */ \ if (data) { *data = val; }
n = DAP_Data.transfer.idle_cycles; \
if (n) { \ /* Capture Timestamp */
PIN_SWDIO_OUT(0U); \ if (request & DAP_TRANSFER_TIMESTAMP) {
for (; n; n--) { \ DAP_Data.timestamp = TIMESTAMP_GET();
SW_CLOCK_CYCLE(); \ }
} \
} \ }
PIN_SWDIO_OUT(1U); \ else if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {
return ((uint8_t)ack); \ DAP_SPI_Generate_Cycle(1);
} \ #if (PRINT_SWD_PROTOCOL == 1)
\ printf("WAIT\r\n");
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \ #endif
/* WAIT or FAULT response */ \
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \ continue;
for (n = 32U+1U; n; n--) { \ // return DAP_TRANSFER_WAIT;
SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \ }
} \ else {
} \ /* Protocol error */
/* Turnaround */ \ DAP_SPI_Disable();
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ PIN_SWDIO_TMS_SET();
SW_CLOCK_CYCLE(); \
} \ DAP_SPI_Enable();
PIN_SWDIO_OUT_ENABLE(); \ DAP_SPI_Protocol_Error_Read();
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
PIN_SWDIO_OUT(0U); \ DAP_SPI_Disable();
for (n = 32U+1U; n; n--) { \ PIN_SWDIO_TMS_SET();
SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \ printf("Protocol Error: Read\r\n");
} \ }
} \
PIN_SWDIO_OUT(1U); \ return ((uint8_t)ack);
return ((uint8_t)ack); \ }
} \ else {
\ /* Write data */
/* Protocol error */ \ parity = ParityEvenUint32(*data);
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \ DAP_SPI_Send_Header(requestByte, &ack, 1); // 1 Trn After ACK
SW_CLOCK_CYCLE(); /* Back off data phase */ \ if (ack == DAP_TRANSFER_OK) {
} \ DAP_SPI_Write_Data(*data, parity);
PIN_SWDIO_OUT_ENABLE(); \ /* Capture Timestamp */
PIN_SWDIO_OUT(1U); \ if (request & DAP_TRANSFER_TIMESTAMP) {
return ((uint8_t)ack); \ DAP_Data.timestamp = TIMESTAMP_GET();
}
/* Idle cycles */
n = DAP_Data.transfer.idle_cycles;
if (n) { DAP_SPI_Generate_Cycle(n); }
DAP_SPI_Disable();
PIN_SWDIO_TMS_SET();
return ((uint8_t)ack);
}
else if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {
/* already turnaround. */
/* TODO: overrun transfer -> for read */
#if (PRINT_SWD_PROTOCOL == 1)
printf("WAIT\r\n");
#endif
continue;
}
else {
//// FIXME: bug
/* Protocol error */
DAP_SPI_Disable();
PIN_SWDIO_TMS_SET();
DAP_SPI_Enable();
DAP_SPI_Protocol_Error_Write();
DAP_SPI_Disable();
PIN_SWDIO_TMS_SET();
printf("Protocol Error: Write\r\n");
}
return ((uint8_t)ack);
}
} while (retryCount++ < 99);
return DAP_TRANSFER_ERROR;
} }

View File

@ -0,0 +1,10 @@
#include "dap_utility.h"
const uint8_t kParityByteTable[256] =
{
#define P2(n) n, n^1, n^1, n
#define P4(n) P2(n), P2(n^1), P2(n^1), P2(n)
#define P6(n) P4(n), P4(n^1), P4(n^1), P4(n)
P6(0), P6(1), P6(1), P6(0)
};

View File

@ -0,0 +1,191 @@
#include <stdio.h>
#include "esp8266/spi_struct.h"
#include "cmsis_compiler.h"
#include "spi_op.h"
#define DAP_SPI SPI1
/**
* @brief Write bits. LSB & little-endian
* Note: No check. The pointer must be valid.
* @param count Number of bits to be written
* @param buf Data Buf
*/
void DAP_SPI_WriteBits(const uint8_t count, const uint8_t *buf)
{
DAP_SPI.user.usr_command = 0;
DAP_SPI.user.usr_addr = 0;
// have data to send
DAP_SPI.user.usr_mosi = 1;
DAP_SPI.user1.usr_mosi_bitlen = count - 1;
// copy data to reg
switch (count)
{
case 8:
DAP_SPI.data_buf[0] = (buf[0] << 0) | (0U << 8) | (0U << 16) | (0U << 24);
break;
case 16:
DAP_SPI.data_buf[0] = (buf[0] << 0) | (buf[1] << 8) | (0x000U << 16) | (0x000U << 24);
break;
case 33: // 32bits data & 1 bit parity
DAP_SPI.data_buf[0] = (buf[0] << 0) | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
DAP_SPI.data_buf[1] = (buf[4] << 0) | (0x000U << 8) | (0x000U << 16) | (0x000U << 24);
break;
case 51: // for line reset
DAP_SPI.data_buf[0] = (buf[0] << 0) | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
DAP_SPI.data_buf[1] = (buf[4] << 0) | (buf[5] << 8) | (buf[2] << 16) | (0x000U << 24);
break;
default:
printf("[ERROR] Using unaligned data!\r\n");
break;
}
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr);
}
/**
* @brief Step1: Packet Request
*
* @param packetHeaderData data from host
* @param ack ack from target
* @param TrnAfterACK num of trn after ack
*/
__FORCEINLINE void DAP_SPI_Send_Header(const uint8_t packetHeaderData, uint8_t *ack, uint8_t TrnAfterACK)
{
uint32_t dataBuf;
// have data to send
DAP_SPI.user.usr_mosi = 1;
DAP_SPI.user1.usr_mosi_bitlen = 8 - 1;
DAP_SPI.user.usr_miso = 1;
// 1 bit Trn(Before ACK) + 3bits ACK + TrnAferACK - 1(prescribed)
DAP_SPI.user1.usr_miso_bitlen = 1U + 3U + TrnAfterACK - 1U;
// copy data to reg
DAP_SPI.data_buf[0] = (packetHeaderData << 0) | (0U << 8) | (0U << 16) | (0U << 24);
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr);
dataBuf = DAP_SPI.data_buf[0];
*ack = (dataBuf >> 1) & 0b111;
}
/**
* @brief Step2: Read Data
*
* @param resData data from target
* @param resParity parity from target
*/
__FORCEINLINE void DAP_SPI_Read_Data(uint32_t* resData, uint8_t* resParity)
{
uint64_t dataBuf;
uint32_t *pU32Data = (uint32_t *)&dataBuf;
DAP_SPI.user.usr_mosi = 0;
DAP_SPI.user.usr_miso = 1;
// 1 bit Trn(End) + 3bits ACK + 32bis data + 1bit parity - 1(prescribed)
DAP_SPI.user1.usr_miso_bitlen = 1U +32U + 1U - 1U;
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr);
pU32Data[0] = DAP_SPI.data_buf[0];
pU32Data[1] = DAP_SPI.data_buf[1];
*resData = (dataBuf >> 0U) & 0xFFFFFFFFU ; // 32bits Response Data
*resParity = (dataBuf >> (0U + 32U)) & 1U; // 3bits ACK + 32bis data
}
/**
* @brief Step2: Write Data
*
* @param data data from host
* @param parity parity from host
*/
__FORCEINLINE void DAP_SPI_Write_Data(uint32_t data, uint8_t parity)
{
DAP_SPI.user.usr_mosi = 1;
DAP_SPI.user.usr_miso = 0;
DAP_SPI.user1.usr_mosi_bitlen = 32U + 1U - 1U; // 32bis data + 1bit parity - 1(prescribed)
// copy data to reg
DAP_SPI.data_buf[0] = data;
DAP_SPI.data_buf[1] = parity;
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr);
}
/**
* @brief Generate Clock Cycle
*
* @param num Cycle Num
*/
__FORCEINLINE void DAP_SPI_Generate_Cycle(uint8_t num)
{
DAP_SPI.user.usr_mosi = 1;
DAP_SPI.user.usr_miso = 0;
DAP_SPI.user1.usr_mosi_bitlen = num - 1U;
DAP_SPI.data_buf[0] = 0x00000000U;
DAP_SPI.cmd.usr = 1;
while (DAP_SPI.cmd.usr);
}
/**
* @brief Generate Protocol Error Cycle
*
*/
__FORCEINLINE void DAP_SPI_Protocol_Error_Read()
{
DAP_SPI.user.usr_mosi = 1;
DAP_SPI.user.usr_miso = 0;
DAP_SPI.user1.usr_mosi_bitlen = 32U + 1U - 1; // 32bit ignore data + 1 bit - 1(prescribed)
DAP_SPI.data_buf[0] = 0xFFFFFFFFU;
DAP_SPI.data_buf[1] = 0xFFFFFFFFU;
DAP_SPI.cmd.usr = 1;
while (DAP_SPI.cmd.usr);
}
/**
* @brief Generate Protocol Error Cycle
*
*/
__FORCEINLINE void DAP_SPI_Protocol_Error_Write()
{
DAP_SPI.user.usr_mosi = 1;
DAP_SPI.user.usr_miso = 0;
DAP_SPI.user1.usr_mosi_bitlen = 1U + 32U + 1U - 1; // 1bit Trn + 32bit ignore data + 1 bit - 1(prescribed)
DAP_SPI.data_buf[0] = 0xFFFFFFFFU;
DAP_SPI.data_buf[1] = 0xFFFFFFFFU;
DAP_SPI.cmd.usr = 1;
while (DAP_SPI.cmd.usr);
}

View File

@ -0,0 +1,158 @@
/**
* @file spi_switch.c
* @author windowsair
* @brief Switching between SPI mode and IO mode
* @version 0.1
* @date 2020-11-25
*
* @copyright Copyright (c) 2020
*
*/
#include <stdbool.h>
#include "esp8266/spi_struct.h"
#include "esp8266/pin_mux_register.h"
#include "esp8266/gpio_struct.h"
#include "cmsis_compiler.h"
#include "spi_switch.h"
#define DAP_SPI SPI1
#define ENTER_CRITICAL() portENTER_CRITICAL()
#define EXIT_CRITICAL() portEXIT_CRITICAL()
typedef enum {
SPI_40MHz_DIV = 2,
// SPI_80MHz_DIV = 1, //// FIXME: high speed clock
} spi_clk_div_t;
/**
* @brief Initialize on first use
*
*/
void DAP_SPI_Init()
{
// Disable flash operation mode
DAP_SPI.user.flash_mode = false;
// Set to Master mode
DAP_SPI.pin.slave_mode = false;
DAP_SPI.slave.slave_mode = false;
// Master uses the entire hardware buffer to improve transmission speed
// If the following fields are enabled, only a part of the buffer is used
DAP_SPI.user.usr_mosi_highpart = false;
DAP_SPI.user.usr_miso_highpart = false;
// Disable cs pin
DAP_SPI.user.cs_setup = false;
DAP_SPI.user.cs_hold = false;
// Duplex transmit
DAP_SPI.user.duplex = true;
// SCLK delay setting
DAP_SPI.user.ck_i_edge = true;
DAP_SPI.ctrl2.mosi_delay_num = 0;
DAP_SPI.ctrl2.miso_delay_num = 0;
// DIO & QIO SPI disable
DAP_SPI.user.fwrite_dual = false;
DAP_SPI.user.fwrite_quad = false;
DAP_SPI.user.fwrite_dio = false;
DAP_SPI.user.fwrite_qio = false;
DAP_SPI.ctrl.fread_dual = false;
DAP_SPI.ctrl.fread_quad = false;
DAP_SPI.ctrl.fread_dio = false;
DAP_SPI.ctrl.fread_qio = false;
DAP_SPI.ctrl.fastrd_mode = true;
// Enable soft reset
DAP_SPI.slave.sync_reset = true;
// Set the clock polarity and phase CPOL = CPHA = 0
DAP_SPI.pin.ck_idle_edge = 1; // HIGH while idle
DAP_SPI.user.ck_out_edge = 0;
// Set data bit order
DAP_SPI.ctrl.wr_bit_order = 1; // SWD -> LSB
DAP_SPI.ctrl.rd_bit_order = 1; // SWD -> LSB
// Set data byte order
DAP_SPI.user.wr_byte_order = 0; // SWD -> litte_endian && Risc V -> litte_endian
DAP_SPI.user.rd_byte_order = 0; // SWD -> litte_endian && Risc V -> litte_endian
// Set dummy
DAP_SPI.user.usr_dummy = 0;
// Initialize HSPI IO
gpio_pin_reg_t pin_reg;
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_HSPI_CLK); // GPIO14 is SPI CLK pin (Clock)
GPIO.enable_w1ts |= (0x1 << 14); // PP Output
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(14));
pin_reg.pullup = 1;
WRITE_PERI_REG(GPIO_PIN_REG(14), pin_reg.val);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_HSPID_MOSI); // GPIO13 is SPI MOSI pin (Master Data Out)
GPIO.enable_w1ts |= (0x1 << 13);
GPIO.pin[13].driver = 0; // PP Output or OD output
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(13));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(13), pin_reg.val);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_HSPIQ_MISO); // GPIO12 is SPI MISO pin (Master Data In)
// esp8266 in is always connected
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(12));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(12), pin_reg.val);
// Set spi clk div
CLEAR_PERI_REG_MASK(PERIPHS_IO_MUX_CONF_U, SPI1_CLK_EQU_SYS_CLK);
DAP_SPI.clock.clk_equ_sysclk = false;
DAP_SPI.clock.clkdiv_pre = 0;
DAP_SPI.clock.clkcnt_n = SPI_40MHz_DIV - 1;
DAP_SPI.clock.clkcnt_h = SPI_40MHz_DIV / 2 - 1;
DAP_SPI.clock.clkcnt_l = SPI_40MHz_DIV - 1;
// Do not use command and addr
DAP_SPI.user.usr_command = 0;
DAP_SPI.user.usr_addr = 0;
}
/**
* @brief Use SPI acclerate
*
*/
void DAP_SPI_Enable()
{
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_HSPID_MOSI); // GPIO13 is SPI MOSI pin (Master Data Out)
}
/**
* @brief Disable SPI
*
*/
__FORCEINLINE void DAP_SPI_Disable()
{
DAP_SPI_Deinit();
}
__FORCEINLINE void DAP_SPI_Deinit()
{
CLEAR_PERI_REG_MASK(PERIPHS_IO_MUX_MTCK_U, (PERIPHS_IO_MUX_FUNC << PERIPHS_IO_MUX_FUNC_S));
// may be unuse
gpio_pin_reg_t pin_reg;
GPIO.enable_w1ts |= (0x1 << 13);
GPIO.pin[13].driver = 0; // OD Output
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(13));
pin_reg.pullup = 1;
WRITE_PERI_REG(GPIO_PIN_REG(13), pin_reg.val);
}

View File

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

View File

@ -272,6 +272,7 @@ static void handleGetDescriptor(usbip_stage2_header *header)
os_printf("low bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8lo); 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("high bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8hi);
os_printf("***Unsupported String descriptor***\r\n"); os_printf("***Unsupported String descriptor***\r\n");
send_stage2_submit(header, 0, 0);
} }
break; break;

View File

@ -1,7 +1,7 @@
#ifndef __USBD_CONFIG_H__ #ifndef __USBD_CONFIG_H__
#define __USBD_CONFIG_H__ #define __USBD_CONFIG_H__
#define USE_WINUSB 0 #include "dap_configuration.h"
// Vendor ID assigned by USB-IF (idVendor). // Vendor ID assigned by USB-IF (idVendor).
#define USBD0_DEV_DESC_IDVENDOR 0xC251 #define USBD0_DEV_DESC_IDVENDOR 0xC251

View File

@ -16,6 +16,7 @@
#include "DAP.h" #include "DAP.h"
#include "esp_libc.h" #include "esp_libc.h"
#include "USBd_config.h" #include "USBd_config.h"
#include "dap_configuration.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
@ -29,8 +30,9 @@
extern int kSock; extern int kSock;
extern TaskHandle_t kDAPTaskHandle; extern TaskHandle_t kDAPTaskHandle;
////TODO: Merge this
#define DAP_PACKET_SIZE 255 int kRestartDAPHandle = 0;
#if (USE_WINUSB == 1) #if (USE_WINUSB == 1)
typedef struct typedef struct
@ -160,6 +162,22 @@ void DAP_Thread(void *argument)
while (1) while (1)
{ {
if (kRestartDAPHandle)
{
vRingbufferDelete(dap_dataIN_handle);
vRingbufferDelete(dap_dataOUT_handle);
dap_dataIN_handle = dap_dataOUT_handle = NULL;
dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL)
{
os_printf("Can not create DAP ringbuf/mux!\r\n");
vTaskDelete(NULL);
}
kRestartDAPHandle = 0;
}
ulTaskNotifyTake(pdFALSE, portMAX_DELAY); ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
packetSize = 0; packetSize = 0;
item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize, item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize,

22
main/dap_configuration.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef __DAP_CONFIGURATION_H__
#define __DAP_CONFIGURATION_H__
/**
* @brief Specify the use of WINUSB
*
*/
#define USE_WINUSB 1
/// 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.
#if (USE_WINUSB == 1)
#define DAP_PACKET_SIZE 512U // 512 for WinUSB.
#else
#define DAP_PACKET_SIZE 255U // 255 for USB HID
#endif
#endif

View File

@ -134,8 +134,8 @@ void app_main()
DAP_Setup(); // DAP Setup DAP_Setup(); // DAP Setup
xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL); xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL);
xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 20, NULL); xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 14, NULL);
xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 22, &kDAPTaskHandle); xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 10, &kDAPTaskHandle);
// SWO Trace Task // SWO Trace Task
//xTaskCreate(SWO_Thread, "swo_task", 1024, NULL, 6, NULL); //xTaskCreate(SWO_Thread, "swo_task", 1024, NULL, 6, NULL);
//xTaskCreate(usart_monitor_task, "uart_task", 512, NULL, 6, NULL); //xTaskCreate(usart_monitor_task, "uart_task", 512, NULL, 6, NULL);

View File

@ -29,16 +29,20 @@
#include "wifi_configuration.h" #include "wifi_configuration.h"
#include "usbip_server.h" #include "usbip_server.h"
extern TaskHandle_t kDAPTaskHandle;
extern int kRestartDAPHandle;
uint8_t kState = ACCEPTING; uint8_t kState = ACCEPTING;
int kSock = -1; int kSock = -1;
void tcp_server_task(void *pvParameters) void tcp_server_task(void *pvParameters)
{ {
uint8_t tcp_rx_buffer[768]; uint8_t tcp_rx_buffer[1024];
char addr_str[128]; char addr_str[128];
int addr_family; int addr_family;
int ip_protocol; int ip_protocol;
int on = 1;
while (1) while (1)
{ {
@ -68,6 +72,9 @@ void tcp_server_task(void *pvParameters)
} }
os_printf("Socket created\r\n"); os_printf("Socket created\r\n");
setsockopt(listen_sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on));
int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
if (err != 0) if (err != 0)
{ {
@ -98,6 +105,8 @@ void tcp_server_task(void *pvParameters)
os_printf("Unable to accept connection: errno %d\r\n", errno); os_printf("Unable to accept connection: errno %d\r\n", errno);
break; break;
} }
setsockopt(kSock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
setsockopt(kSock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on));
os_printf("Socket accepted\r\n"); os_printf("Socket accepted\r\n");
while (1) while (1)
@ -158,6 +167,10 @@ void tcp_server_task(void *pvParameters)
if (kState == EMULATING) if (kState == EMULATING)
kState = ACCEPTING; kState = ACCEPTING;
// Restart DAP Handle
kRestartDAPHandle = 1;
xTaskNotifyGive(kDAPTaskHandle);
//shutdown(listen_sock, 0); //shutdown(listen_sock, 0);
//close(listen_sock); //close(listen_sock);
//vTaskDelay(5); //vTaskDelay(5);

View File

@ -123,8 +123,8 @@ CONFIG_TASK_WDT_PANIC=y
CONFIG_TASK_WDT_TIMEOUT_15N=y CONFIG_TASK_WDT_TIMEOUT_15N=y
CONFIG_TASK_WDT_TIMEOUT_S=15 CONFIG_TASK_WDT_TIMEOUT_S=15
CONFIG_RESET_REASON=y CONFIG_RESET_REASON=y
CONFIG_WIFI_PPT_TASKSTACK_SIZE=2048 CONFIG_WIFI_PPT_TASKSTACK_SIZE=4096
CONFIG_EVENT_LOOP_STACK_SIZE=2048 CONFIG_EVENT_LOOP_STACK_SIZE=4096
# CONFIG_ESP8266_OTA_FROM_OLD is not set # CONFIG_ESP8266_OTA_FROM_OLD is not set
# CONFIG_ESP8266_BOOT_COPY_APP is not set # CONFIG_ESP8266_BOOT_COPY_APP is not set
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
@ -135,9 +135,9 @@ CONFIG_WIFI_TX_RATE_SEQUENCE_FROM_HIGH=y
# CONFIG_ESP8266_WIFI_QOS_ENABLED is not set # CONFIG_ESP8266_WIFI_QOS_ENABLED is not set
# CONFIG_ESP8266_WIFI_AMPDU_RX_ENABLED is not set # CONFIG_ESP8266_WIFI_AMPDU_RX_ENABLED is not set
# CONFIG_ESP8266_WIFI_AMSDU_ENABLED is not set # CONFIG_ESP8266_WIFI_AMSDU_ENABLED is not set
CONFIG_ESP8266_WIFI_RX_BUFFER_NUM=26 CONFIG_ESP8266_WIFI_RX_BUFFER_NUM=28
CONFIG_ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM=4 CONFIG_ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM=8
CONFIG_ESP8266_WIFI_RX_PKT_NUM=7 CONFIG_ESP8266_WIFI_RX_PKT_NUM=16
CONFIG_ESP8266_WIFI_TX_PKT_NUM=6 CONFIG_ESP8266_WIFI_TX_PKT_NUM=6
CONFIG_ESP8266_WIFI_NVS_ENABLED=y CONFIG_ESP8266_WIFI_NVS_ENABLED=y
CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET=y CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET=y
@ -183,9 +183,8 @@ CONFIG_TCPIP_RECVMBOX_SIZE=64
CONFIG_LWIP_ARP_TABLE_SIZE=10 CONFIG_LWIP_ARP_TABLE_SIZE=10
CONFIG_LWIP_ARP_MAXAGE=300 CONFIG_LWIP_ARP_MAXAGE=300
# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set # CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set
CONFIG_LWIP_SOCKET_MULTITHREAD=y # CONFIG_LWIP_SOCKET_MULTITHREAD is not set
CONFIG_ENABLE_NONBLOCK_SPEEDUP=y CONFIG_ENABLE_NONBLOCK_SPEEDUP=y
CONFIG_SET_SOLINGER_DEFAULT=y
CONFIG_ESP_UDP_SYNC_SEND=y CONFIG_ESP_UDP_SYNC_SEND=y
CONFIG_ESP_UDP_SYNC_RETRY_MAX=5 CONFIG_ESP_UDP_SYNC_RETRY_MAX=5
CONFIG_LWIP_MAX_SOCKETS=10 CONFIG_LWIP_MAX_SOCKETS=10
@ -214,13 +213,13 @@ CONFIG_ESP_DNS=y
CONFIG_DNS_MAX_SERVERS=3 CONFIG_DNS_MAX_SERVERS=3
# CONFIG_LWIP_NETIF_LOOPBACK is not set # CONFIG_LWIP_NETIF_LOOPBACK is not set
CONFIG_TCP_HIGH_SPEED_RETRANSMISSION=y CONFIG_TCP_HIGH_SPEED_RETRANSMISSION=y
CONFIG_LWIP_MAX_ACTIVE_TCP=5 CONFIG_LWIP_MAX_ACTIVE_TCP=16
CONFIG_LWIP_MAX_LISTENING_TCP=8 CONFIG_LWIP_MAX_LISTENING_TCP=8
CONFIG_TCP_MAXRTX=12 CONFIG_TCP_MAXRTX=12
CONFIG_TCP_SYNMAXRTX=6 CONFIG_TCP_SYNMAXRTX=6
CONFIG_TCP_MSS=1460 CONFIG_TCP_MSS=1460
CONFIG_TCP_SND_BUF_DEFAULT=2920 CONFIG_TCP_SND_BUF_DEFAULT=2920
CONFIG_TCP_WND_DEFAULT=5840 CONFIG_TCP_WND_DEFAULT=10240
CONFIG_TCP_RECVMBOX_SIZE=16 CONFIG_TCP_RECVMBOX_SIZE=16
CONFIG_TCP_QUEUE_OOSEQ=y CONFIG_TCP_QUEUE_OOSEQ=y
CONFIG_TCP_OVERSIZE_MSS=y CONFIG_TCP_OVERSIZE_MSS=y