diff --git a/.gitignore b/.gitignore
index e524d79..9a47b5a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.vscode/
build/
+tmp/
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0eb1581..7bc2902 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,5 +3,7 @@
cmake_minimum_required(VERSION 3.5)
#set(COMPONENT_DIRS "${IDF_PATH}/components ${PROJECT_PATH}/components")
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/main)
+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp8266_dap)
diff --git a/README.md b/README.md
index c01e68d..943ef50 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@

Wireless ESP8266 DAP
-[](https://travis-ci.com/windowsair/wireless-esp8266-dap) master
-[](https://travis-ci.com/windowsair/wireless-esp8266-dap) develop
+[](https://github.com/windowsair/wireless-esp8266-dap/actions?query=branch%3Amaster) master
+[](https://github.com/windowsair/wireless-esp8266-dap/actions?query=branch%3Adevelop) develop
[](https://github.com/windowsair/wireless-esp8266-dap/LICENSE) [](https://github.com/windowsair/wireless-esp8266-dap/pulls) [](https://github.com/windowsair/wireless-esp8266-dap)
@@ -32,8 +32,9 @@ Realized by USBIP and CMSIS-DAP protocol stack.
- [ ] SWO Streaming Trace
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
+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
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:
```bash
-# HID Mode
+# HID Mode only
# for pre-compiled version on SourceForge
# or usbip old version
.\usbip.exe -D -a 1-1
# HID Mode Or WinUSB Mode
# for usbip-win 0.3.0 kmdf ude
-.\usbip.exe attach-ude -r -b 1-1
+.\usbip.exe attach_ude -r -b 1-1
```
@@ -141,6 +150,8 @@ Then test it under MDK:
## Develop
+0. Check other branches to know the latest development progress.
+
1. Use WinUSB Mode:
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
-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 pull](https://github.com/windowsair/wireless-esp8266-dap/pulls)
### Issue
+2020.12.1
+
+TCP transmission speed needs to be further improved.
+
2020.11.11
Winusb is now available, but it is very slow.
diff --git a/components/DAP/CMakeLists.txt b/components/DAP/CMakeLists.txt
index 3eec5a2..c18752a 100644
--- a/components/DAP/CMakeLists.txt
+++ b/components/DAP/CMakeLists.txt
@@ -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_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()
\ No newline at end of file
diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h
index 7121a2e..fcf2d24 100644
--- a/components/DAP/config/DAP_config.h
+++ b/components/DAP/config/DAP_config.h
@@ -36,6 +36,8 @@
#include "timer_struct.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
@@ -64,7 +66,7 @@ This information includes:
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<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.
+#define MAX_USER_CLOCK 16000000 ///< Specifies the max Debug Clock in Hz.
/// Number of processor cycles for I/O Port write operations.
/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O
@@ -96,18 +98,11 @@ This information includes:
#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.
+#define DAP_PACKET_COUNT 255 ///< Specifies number of packets buffered.
/// Indicate that UART Serial Wire Output (SWO) trace is available.
/// This information is returned by the command \ref DAP_Info as part of Capabilities.
@@ -189,12 +184,13 @@ __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str)
// 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_SWDIO 12
+#define PIN_SWDIO_MOSI 13 // SPI MOSI
+#define PIN_SWCLK 14
+#define PIN_TDO 4
+#define PIN_TDI 0
#define PIN_nTRST 0 // optional
-#define PIN_nRESET 14
+#define PIN_nRESET 5
// LED_BUILTIN
#define PIN_LED_CONNECTED 2
// LED_BUILTIN
@@ -300,18 +296,25 @@ __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);
+
+ // PIN_SWCLK -> OUTPUT
+ // PIN_SWDIO -> 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);
+
+ 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.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_nRESET, GPIO_MODE_DEF_DISABLE);
- GPIO.pin[PIN_SWCLK].driver = 0;
- GPIO.enable_w1tc |= (0x1 << PIN_SWCLK);
+ // 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_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_TDO].driver = 0;
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)
{
- 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)
{
- 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)
{
//set bit
- GPIO.out_w1ts |= (0x1 << PIN_SWDIO);
+ GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI);
}
else
{
//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)
{
// Need fast response
-
+ //// TODO: low speed
// set \ref gpio_set_direction -> OUTPUT
- GPIO.enable_w1ts |= (0x1 << PIN_SWDIO);
- GPIO.pin[PIN_SWDIO].driver = 0;
+ // GPIO.enable_w1ts |= (0x1 << PIN_SWDIO_MOSI);
+ // 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
// set \ref gpio_set_dircetion -> INPUT
// esp8266 input is always connected
- GPIO.enable_w1tc |= (0x1 << PIN_SWDIO);
- GPIO.pin[PIN_SWDIO].driver = 0;
+ // GPIO.enable_w1tc |= (0x1 << PIN_SWDIO_MOSI);
+ // GPIO.pin[PIN_SWDIO_MOSI].driver = 0;
+ GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI);
}
// TDI Pin I/O ---------------------------------------------
@@ -576,17 +589,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void)
*/
__STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit)
{
- // ////TODO: What does this mean? ? ?
- // if ((bit & 1U) == 1)
- // {
- // //set bit
- // GPIO.out_w1ts |= (0x1 << PIN_nTRST);
- // }
- // else
- // {
- // //reset bit
- // GPIO.out_w1tc |= (0x1 << PIN_nTRST);
- // }
+ // Vendor reset sequence
; // not available
}
@@ -611,7 +614,8 @@ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void)
*/
__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit)
{
- ////TODO: What does this mean? ? ?
+ // Vendor reset sequence
+ //// FIXME: unavailable
if ((bit & 1U) == 1)
{
//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)
{
+ DAP_SPI_Init();
+ DAP_SPI_Disable();
+
+
// 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_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);
@@ -745,6 +753,8 @@ __STATIC_INLINE void DAP_SETUP(void)
LED_CONNECTED_OUT(0);
gpio_set_direction(PIN_LED_RUNNING, GPIO_MODE_DEF_OUTPUT);
LED_RUNNING_OUT(0);
+
+ PORT_OFF();
}
/** Reset Target Device with custom specific I/O pin or command sequence.
diff --git a/components/DAP/include/cmsis_compiler.h b/components/DAP/include/cmsis_compiler.h
index aafbe21..9d032bb 100644
--- a/components/DAP/include/cmsis_compiler.h
+++ b/components/DAP/include/cmsis_compiler.h
@@ -7,6 +7,9 @@
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline __attribute__((always_inline))
#endif
+#ifndef __FORCEINLINE
+ #define __FORCEINLINE inline __attribute__((always_inline))
+#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
diff --git a/components/DAP/include/dap_utility.h b/components/DAP/include/dap_utility.h
new file mode 100644
index 0000000..ee25c6f
--- /dev/null
+++ b/components/DAP/include/dap_utility.h
@@ -0,0 +1,33 @@
+#ifndef __DAP_UTILITY_H__
+#define __DAP_UTILITY_H__
+
+#include
+
+#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
diff --git a/components/DAP/include/spi_op.h b/components/DAP/include/spi_op.h
new file mode 100644
index 0000000..abfe12d
--- /dev/null
+++ b/components/DAP/include/spi_op.h
@@ -0,0 +1,19 @@
+#ifndef __SPI_OP_H__
+#define __SPI_OP_H__
+
+#include
+
+
+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
diff --git a/components/DAP/include/spi_switch.h b/components/DAP/include/spi_switch.h
new file mode 100644
index 0000000..3b7eb80
--- /dev/null
+++ b/components/DAP/include/spi_switch.h
@@ -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
diff --git a/components/DAP/source/SW_DP.c b/components/DAP/source/SW_DP.c
index 803cf42..600809d 100644
--- a/components/DAP/source/SW_DP.c
+++ b/components/DAP/source/SW_DP.c
@@ -28,6 +28,12 @@
#include "DAP_config.h"
#include "DAP.h"
+#include "spi_op.h"
+#include "spi_switch.h"
+#include "dap_utility.h"
+
+// Debug
+#define PRINT_SWD_PROTOCOL 0
// SW Macros
@@ -54,7 +60,8 @@
PIN_SWCLK_SET(); \
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
@@ -63,25 +70,13 @@
// 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--;
+ if (count != 8 && count != 16 && count!= 51)
+ {
+ printf("[ERROR] wrong SWJ Swquence length:%d\r\n", (int)count);
+ return;
}
+ DAP_SPI_Enable();
+ DAP_SPI_WriteBits(count, data);
}
#endif
@@ -133,131 +128,176 @@ void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) {
// request: A[3:2] RnW APnDP
// data: DATA[31: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) { \
- uint32_t ack; \
- uint32_t bit; \
- uint32_t val; \
- uint32_t parity; \
- \
- uint32_t n; \
- \
- /* Packet Request */ \
- parity = 0U; \
- SW_WRITE_BIT(1U); /* Start Bit */ \
- bit = request >> 0; \
- SW_WRITE_BIT(bit); /* APnDP Bit */ \
- parity += bit; \
- bit = request >> 1; \
- SW_WRITE_BIT(bit); /* RnW Bit */ \
- parity += bit; \
- bit = request >> 2; \
- SW_WRITE_BIT(bit); /* A2 Bit */ \
- parity += bit; \
- bit = request >> 3; \
- SW_WRITE_BIT(bit); /* A3 Bit */ \
- parity += bit; \
- SW_WRITE_BIT(parity); /* Parity Bit */ \
- SW_WRITE_BIT(0U); /* Stop Bit */ \
- SW_WRITE_BIT(1U); /* Park Bit */ \
- \
- /* Turnaround */ \
- PIN_SWDIO_OUT_DISABLE(); \
- for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
- SW_CLOCK_CYCLE(); \
- } \
- \
- /* Acknowledge response */ \
- SW_READ_BIT(bit); \
- ack = bit << 0; \
- SW_READ_BIT(bit); \
- ack |= bit << 1; \
- SW_READ_BIT(bit); \
- ack |= bit << 2; \
- \
- if (ack == DAP_TRANSFER_OK) { /* OK response */ \
- /* Data transfer */ \
- if (request & DAP_TRANSFER_RnW) { \
- /* Read data */ \
- val = 0U; \
- parity = 0U; \
- for (n = 32U; n; n--) { \
- SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
- parity += bit; \
- val >>= 1; \
- val |= bit << 31; \
- } \
- SW_READ_BIT(bit); /* Read Parity */ \
- if ((parity ^ bit) & 1U) { \
- ack = DAP_TRANSFER_ERROR; \
- } \
- if (data) { *data = val; } \
- /* Turnaround */ \
- for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
- SW_CLOCK_CYCLE(); \
- } \
- PIN_SWDIO_OUT_ENABLE(); \
- } else { \
- /* Turnaround */ \
- for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
- SW_CLOCK_CYCLE(); \
- } \
- PIN_SWDIO_OUT_ENABLE(); \
- /* Write data */ \
- val = *data; \
- parity = 0U; \
- for (n = 32U; n; n--) { \
- SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
- parity += val; \
- val >>= 1; \
- } \
- SW_WRITE_BIT(parity); /* Write Parity Bit */ \
- } \
- /* Capture Timestamp */ \
- if (request & DAP_TRANSFER_TIMESTAMP) { \
- DAP_Data.timestamp = TIMESTAMP_GET(); \
- } \
- /* Idle cycles */ \
- n = DAP_Data.transfer.idle_cycles; \
- if (n) { \
- PIN_SWDIO_OUT(0U); \
- for (; n; n--) { \
- SW_CLOCK_CYCLE(); \
- } \
- } \
- PIN_SWDIO_OUT(1U); \
- return ((uint8_t)ack); \
- } \
- \
- if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
- /* WAIT or FAULT response */ \
- if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \
- for (n = 32U+1U; n; n--) { \
- SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
- } \
- } \
- /* Turnaround */ \
- for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
- SW_CLOCK_CYCLE(); \
- } \
- PIN_SWDIO_OUT_ENABLE(); \
- if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
- PIN_SWDIO_OUT(0U); \
- for (n = 32U+1U; n; n--) { \
- SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
- } \
- } \
- PIN_SWDIO_OUT(1U); \
- return ((uint8_t)ack); \
- } \
- \
- /* Protocol error */ \
- for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \
- SW_CLOCK_CYCLE(); /* Back off data phase */ \
- } \
- PIN_SWDIO_OUT_ENABLE(); \
- PIN_SWDIO_OUT(1U); \
- return ((uint8_t)ack); \
+ SWD_Transfer_Common(request,data); \
+ return 1; \
+}
+
+static uint8_t SWD_Transfer_Common (uint32_t request, uint32_t *data) {
+ uint8_t ack;
+ // uint32_t bit;
+ uint32_t val;
+ uint8_t parity;
+ uint8_t computedParity;
+
+ uint32_t n;
+
+ int retryCount = 0;
+ const uint8_t constantBits = 0b10000001U; /* Start Bit & Stop Bit & Park Bit is fixed. */
+ uint8_t requestByte; /* LSB */
+
+
+ DAP_SPI_Enable();
+ do {
+ requestByte = constantBits | (((uint8_t)(request & 0xFU)) << 1U) | (ParityEvenUint8(request & 0xFU) << 5U);
+ /* For 4bit, Parity can be equivalent to 8bit with all 0 high bits */
+
+ #if (PRINT_SWD_PROTOCOL == 1)
+ switch (requestByte)
+ {
+ case 0xA5U:
+ printf("IDCODE\r\n");
+ break;
+ case 0xA9U:
+ printf("W CTRL/STAT\r\n");
+ break;
+ case 0xBDU:
+ printf("RDBUFF\r\n");
+ break;
+ case 0x8DU:
+ printf("R CTRL/STAT\r\n");
+ break;
+ case 0x81U:
+ printf("W ABORT\r\n");
+ break;
+ case 0xB1U:
+ printf("W SELECT\r\n");
+ break;
+ case 0xBBU:
+ printf("W APc\r\n");
+ break;
+ case 0x9FU:
+ printf("R APc\r\n");
+ break;
+ case 0x8BU:
+ printf("W AP4\r\n");
+ break;
+ case 0xA3U:
+ printf("W AP0\r\n");
+ break;
+ case 0X87U:
+ printf("R AP0\r\n");
+ break;
+ case 0xB7U:
+ printf("R AP8\r\n");
+ break;
+ default:
+ //W AP8
+ printf("Unknown:%08x\r\n", requestByte);
+ break;
+ }
+ #endif
+
+
+
+ if (request & DAP_TRANSFER_RnW) {
+ /* Read data */
+
+ DAP_SPI_Send_Header(requestByte, &ack, 0); // 0 Trn After ACK
+ if (ack == DAP_TRANSFER_OK) {
+ DAP_SPI_Read_Data(&val, &parity);
+ computedParity = ParityEvenUint32(val);
+
+ if ((computedParity ^ parity) & 1U) {
+ ack = DAP_TRANSFER_ERROR;
+ }
+ if (data) { *data = val; }
+
+ /* Capture Timestamp */
+ if (request & DAP_TRANSFER_TIMESTAMP) {
+ DAP_Data.timestamp = TIMESTAMP_GET();
+ }
+
+ }
+ else if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {
+ DAP_SPI_Generate_Cycle(1);
+ #if (PRINT_SWD_PROTOCOL == 1)
+ printf("WAIT\r\n");
+ #endif
+
+ continue;
+ // return DAP_TRANSFER_WAIT;
+ }
+ else {
+ /* Protocol error */
+ DAP_SPI_Disable();
+ PIN_SWDIO_TMS_SET();
+
+ DAP_SPI_Enable();
+ DAP_SPI_Protocol_Error_Read();
+
+ DAP_SPI_Disable();
+ PIN_SWDIO_TMS_SET();
+ printf("Protocol Error: Read\r\n");
+ }
+
+ return ((uint8_t)ack);
+ }
+ else {
+ /* Write data */
+ parity = ParityEvenUint32(*data);
+ DAP_SPI_Send_Header(requestByte, &ack, 1); // 1 Trn After ACK
+ if (ack == DAP_TRANSFER_OK) {
+ DAP_SPI_Write_Data(*data, parity);
+ /* Capture Timestamp */
+ if (request & DAP_TRANSFER_TIMESTAMP) {
+ DAP_Data.timestamp = TIMESTAMP_GET();
+ }
+ /* Idle cycles */
+ n = DAP_Data.transfer.idle_cycles;
+ if (n) { DAP_SPI_Generate_Cycle(n); }
+
+ DAP_SPI_Disable();
+ PIN_SWDIO_TMS_SET();
+
+ return ((uint8_t)ack);
+ }
+ else if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {
+ /* already turnaround. */
+
+ /* TODO: overrun transfer -> for read */
+ #if (PRINT_SWD_PROTOCOL == 1)
+ printf("WAIT\r\n");
+ #endif
+
+ 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;
+
+
}
diff --git a/components/DAP/source/dap_utility.c b/components/DAP/source/dap_utility.c
new file mode 100644
index 0000000..94c0381
--- /dev/null
+++ b/components/DAP/source/dap_utility.c
@@ -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)
+};
diff --git a/components/DAP/source/spi_op.c b/components/DAP/source/spi_op.c
new file mode 100644
index 0000000..8deefaf
--- /dev/null
+++ b/components/DAP/source/spi_op.c
@@ -0,0 +1,191 @@
+#include
+
+#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);
+}
diff --git a/components/DAP/source/spi_switch.c b/components/DAP/source/spi_switch.c
new file mode 100644
index 0000000..855ecc4
--- /dev/null
+++ b/components/DAP/source/spi_switch.c
@@ -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
+
+#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);
+}
\ No newline at end of file
diff --git a/components/README.md b/components/README.md
deleted file mode 100644
index 3fc0da1..0000000
--- a/components/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# TODO
-1. USB
\ No newline at end of file
diff --git a/components/USBIP/USB_handle.c b/components/USBIP/USB_handle.c
index 0ea27c5..e806f1e 100644
--- a/components/USBIP/USB_handle.c
+++ b/components/USBIP/USB_handle.c
@@ -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("high bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8hi);
os_printf("***Unsupported String descriptor***\r\n");
+ send_stage2_submit(header, 0, 0);
}
break;
diff --git a/components/USBIP/USBd_config.h b/components/USBIP/USBd_config.h
index dc3a3e2..188b529 100644
--- a/components/USBIP/USBd_config.h
+++ b/components/USBIP/USBd_config.h
@@ -1,7 +1,7 @@
#ifndef __USBD_CONFIG_H__
#define __USBD_CONFIG_H__
-#define USE_WINUSB 0
+#include "dap_configuration.h"
// Vendor ID assigned by USB-IF (idVendor).
#define USBD0_DEV_DESC_IDVENDOR 0xC251
diff --git a/main/DAP_handle.c b/main/DAP_handle.c
index 03c45f3..ff7f2cc 100644
--- a/main/DAP_handle.c
+++ b/main/DAP_handle.c
@@ -1,268 +1,286 @@
-/**
- * @file DAP_handle.c
- * @brief Handle DAP packets and transaction push
- * @version 0.3
- * @date 2020-02-04 first version
- * 2020-11-11 support WinUSB mode
- *
- * @copyright Copyright (c) 2020
- *
- */
-
-#include
-#include
-#include "usbip_server.h"
-#include "DAP_handle.h"
-#include "DAP.h"
-#include "esp_libc.h"
-#include "USBd_config.h"
-
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "freertos/ringbuf.h"
-#include "freertos/semphr.h"
-
-#include "lwip/err.h"
-#include "lwip/sockets.h"
-#include "lwip/sys.h"
-#include
-
-extern int kSock;
-extern TaskHandle_t kDAPTaskHandle;
-////TODO: Merge this
-#define DAP_PACKET_SIZE 255
-
-#if (USE_WINUSB == 1)
-typedef struct
-{
- uint32_t length;
- uint8_t buf[DAP_PACKET_SIZE];
-} DAPPacetDataType;
-#else
-typedef struct
-{
- uint8_t buf[DAP_PACKET_SIZE];
-} DAPPacetDataType;
-#endif
-
-
-#define DAP_HANDLE_SIZE (sizeof(DAPPacetDataType))
-
-static DAPPacetDataType DAPDataProcessed;
-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)
- send_stage2_submit(header, 0, 0);
-
- // always send constant size buf -> cuz we don't care about the IN packet size
- // and to unify the style, we set aside the length of the section
- xRingbufferSend(dap_dataIN_handle, data_in - sizeof(uint32_t), DAP_HANDLE_SIZE, portMAX_DELAY);
- xTaskNotifyGive(kDAPTaskHandle);
-
-#else
- send_stage2_submit(header, 0, 0);
-
- xRingbufferSend(dap_dataIN_handle, data_in, DAP_HANDLE_SIZE, portMAX_DELAY);
- xTaskNotifyGive(kDAPTaskHandle);
-
-#endif
-
- // dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out);
- // //handle_dap_data_response(header);
- // send_stage2_submit(header, 0, 0);
-}
-
-void handle_dap_data_response(usbip_stage2_header *header)
-{
- return;
- // int resLength = dap_respond & 0xFFFF;
- // if (resLength)
- // {
-
- // send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, resLength);
- // dap_respond = 0;
- // }
- // else
- // {
- // send_stage2_submit(header, 0, 0);
- // }
-}
-
-void handle_swo_trace_response(usbip_stage2_header *header)
-{
- // TODO:
- send_stage2_submit(header, 0, 0);
- return;
-
- if (swo_trace_respond)
- {
- swo_trace_respond = 0;
- //send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, 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_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
- dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
- data_response_mux = xSemaphoreCreateMutex();
- size_t packetSize;
- int resLength;
- DAPPacetDataType *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 = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize,
- (1 / portTICK_RATE_MS), DAP_HANDLE_SIZE);
- if (packetSize == 0)
- {
- break;
- }
-
- else if (packetSize < DAP_HANDLE_SIZE)
- {
- os_printf("Wrong data in packet size:%d , data in remain: %d\r\n", packetSize, (int)xRingbufferGetMaxItemSize(dap_dataIN_handle));
- vRingbufferReturnItem(dap_dataIN_handle, (void *)item);
- break;
- // This may not happen because there is a semaphore acquisition
- }
-
- if (item->buf[0] == ID_DAP_QueueCommands)
- {
- item->buf[0] = ID_DAP_ExecuteCommands;
- }
-
- resLength = DAP_ProcessCommand((uint8_t *)item->buf, (uint8_t *)DAPDataProcessed.buf); // use first 4 byte to save length
- resLength &= 0xFFFF; // res length in lower 16 bits
-
- vRingbufferReturnItem(dap_dataIN_handle, (void *)item); // process done.
-
- // now prepare to reply
- #if (USE_WINUSB == 1)
- DAPDataProcessed.length = resLength;
- #endif
- xRingbufferSend(dap_dataOUT_handle, (void *)&DAPDataProcessed, DAP_HANDLE_SIZE, portMAX_DELAY);
-
- if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
- {
- ++dap_respond;
- xSemaphoreGive(data_response_mux);
- }
- }
- }
-}
-
-int fast_reply(uint8_t *buf, uint32_t length)
-{
- if (length == 48 && buf[3] == 1 && buf[15] == 1 && buf[19] == 1)
- {
- if (dap_respond > 0)
- {
- DAPPacetDataType *item;
- size_t packetSize = 0;
- item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize,
- (10 / portTICK_RATE_MS), DAP_HANDLE_SIZE);
- if (packetSize == DAP_HANDLE_SIZE)
- {
- unpack((uint32_t *)buf, sizeof(usbip_stage2_header));
-
- #if (USE_WINUSB == 1)
- uint32_t resLength = item->length;
- send_stage2_submit_data((usbip_stage2_header *)buf, 0, item->buf, resLength);
- #else
- send_stage2_submit_data((usbip_stage2_header *)buf, 0, item->buf, DAP_HANDLE_SIZE);
- #endif
-
-
- if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
- {
- --dap_respond;
- xSemaphoreGive(data_response_mux);
- }
-
- vRingbufferReturnItem(dap_dataOUT_handle, (void *)item);
- return 1;
- }
- else if (packetSize > 0)
- {
- os_printf("Wrong data out packet size:%d!\r\n", packetSize);
- }
- ////TODO: fast reply
- }
- else
- {
- //// TODO: ep0 dir 0 ?
- buf[0x3] = 0x3; // command
- buf[0xF] = 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]);
- }
+/**
+ * @file DAP_handle.c
+ * @brief Handle DAP packets and transaction push
+ * @version 0.3
+ * @date 2020-02-04 first version
+ * 2020-11-11 support WinUSB mode
+ *
+ * @copyright Copyright (c) 2020
+ *
+ */
+
+#include
+#include
+#include "usbip_server.h"
+#include "DAP_handle.h"
+#include "DAP.h"
+#include "esp_libc.h"
+#include "USBd_config.h"
+#include "dap_configuration.h"
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/ringbuf.h"
+#include "freertos/semphr.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include
+
+extern int kSock;
+extern TaskHandle_t kDAPTaskHandle;
+
+int kRestartDAPHandle = 0;
+
+
+#if (USE_WINUSB == 1)
+typedef struct
+{
+ uint32_t length;
+ uint8_t buf[DAP_PACKET_SIZE];
+} DAPPacetDataType;
+#else
+typedef struct
+{
+ uint8_t buf[DAP_PACKET_SIZE];
+} DAPPacetDataType;
+#endif
+
+
+#define DAP_HANDLE_SIZE (sizeof(DAPPacetDataType))
+
+static DAPPacetDataType DAPDataProcessed;
+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)
+ send_stage2_submit(header, 0, 0);
+
+ // always send constant size buf -> cuz we don't care about the IN packet size
+ // and to unify the style, we set aside the length of the section
+ xRingbufferSend(dap_dataIN_handle, data_in - sizeof(uint32_t), DAP_HANDLE_SIZE, portMAX_DELAY);
+ xTaskNotifyGive(kDAPTaskHandle);
+
+#else
+ send_stage2_submit(header, 0, 0);
+
+ xRingbufferSend(dap_dataIN_handle, data_in, DAP_HANDLE_SIZE, portMAX_DELAY);
+ xTaskNotifyGive(kDAPTaskHandle);
+
+#endif
+
+ // dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out);
+ // //handle_dap_data_response(header);
+ // send_stage2_submit(header, 0, 0);
+}
+
+void handle_dap_data_response(usbip_stage2_header *header)
+{
+ return;
+ // int resLength = dap_respond & 0xFFFF;
+ // if (resLength)
+ // {
+
+ // send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, resLength);
+ // dap_respond = 0;
+ // }
+ // else
+ // {
+ // send_stage2_submit(header, 0, 0);
+ // }
+}
+
+void handle_swo_trace_response(usbip_stage2_header *header)
+{
+ // TODO:
+ send_stage2_submit(header, 0, 0);
+ return;
+
+ if (swo_trace_respond)
+ {
+ swo_trace_respond = 0;
+ //send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, 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_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
+ dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
+ data_response_mux = xSemaphoreCreateMutex();
+ size_t packetSize;
+ int resLength;
+ DAPPacetDataType *item;
+
+ if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL ||
+ data_response_mux == NULL)
+ {
+ os_printf("Can not create DAP ringbuf/mux!\r\n");
+ vTaskDelete(NULL);
+ }
+ for (;;)
+ {
+
+ while (1)
+ {
+ if (kRestartDAPHandle)
+ {
+ vRingbufferDelete(dap_dataIN_handle);
+ vRingbufferDelete(dap_dataOUT_handle);
+ dap_dataIN_handle = dap_dataOUT_handle = NULL;
+
+ dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
+ dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
+ if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL)
+ {
+ os_printf("Can not create DAP ringbuf/mux!\r\n");
+ vTaskDelete(NULL);
+ }
+ kRestartDAPHandle = 0;
+ }
+
+ ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
+ packetSize = 0;
+ item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize,
+ (1 / portTICK_RATE_MS), DAP_HANDLE_SIZE);
+ if (packetSize == 0)
+ {
+ break;
+ }
+
+ else if (packetSize < DAP_HANDLE_SIZE)
+ {
+ os_printf("Wrong data in packet size:%d , data in remain: %d\r\n", packetSize, (int)xRingbufferGetMaxItemSize(dap_dataIN_handle));
+ vRingbufferReturnItem(dap_dataIN_handle, (void *)item);
+ break;
+ // This may not happen because there is a semaphore acquisition
+ }
+
+ if (item->buf[0] == ID_DAP_QueueCommands)
+ {
+ item->buf[0] = ID_DAP_ExecuteCommands;
+ }
+
+ resLength = DAP_ProcessCommand((uint8_t *)item->buf, (uint8_t *)DAPDataProcessed.buf); // use first 4 byte to save length
+ resLength &= 0xFFFF; // res length in lower 16 bits
+
+ vRingbufferReturnItem(dap_dataIN_handle, (void *)item); // process done.
+
+ // now prepare to reply
+ #if (USE_WINUSB == 1)
+ DAPDataProcessed.length = resLength;
+ #endif
+ xRingbufferSend(dap_dataOUT_handle, (void *)&DAPDataProcessed, DAP_HANDLE_SIZE, portMAX_DELAY);
+
+ if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
+ {
+ ++dap_respond;
+ xSemaphoreGive(data_response_mux);
+ }
+ }
+ }
+}
+
+int fast_reply(uint8_t *buf, uint32_t length)
+{
+ if (length == 48 && buf[3] == 1 && buf[15] == 1 && buf[19] == 1)
+ {
+ if (dap_respond > 0)
+ {
+ DAPPacetDataType *item;
+ size_t packetSize = 0;
+ item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize,
+ (10 / portTICK_RATE_MS), DAP_HANDLE_SIZE);
+ if (packetSize == DAP_HANDLE_SIZE)
+ {
+ unpack((uint32_t *)buf, sizeof(usbip_stage2_header));
+
+ #if (USE_WINUSB == 1)
+ uint32_t resLength = item->length;
+ send_stage2_submit_data((usbip_stage2_header *)buf, 0, item->buf, resLength);
+ #else
+ send_stage2_submit_data((usbip_stage2_header *)buf, 0, item->buf, DAP_HANDLE_SIZE);
+ #endif
+
+
+ if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
+ {
+ --dap_respond;
+ xSemaphoreGive(data_response_mux);
+ }
+
+ vRingbufferReturnItem(dap_dataOUT_handle, (void *)item);
+ return 1;
+ }
+ else if (packetSize > 0)
+ {
+ os_printf("Wrong data out packet size:%d!\r\n", packetSize);
+ }
+ ////TODO: fast reply
+ }
+ else
+ {
+ //// TODO: ep0 dir 0 ?
+ buf[0x3] = 0x3; // command
+ buf[0xF] = 0; // direction
+ buf[0x16] = 0;
+ buf[0x17] = 0;
+ buf[27] = 0;
+ buf[39] = 0;
+ send(kSock, buf, 48, 0);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void unpack(void *data, int size)
+{
+ // Ignore the setup field
+ int sz = (size / sizeof(uint32_t)) - 2;
+ uint32_t *ptr = (uint32_t *)data;
+
+ for (int i = 0; i < sz; i++)
+ {
+ ptr[i] = ntohl(ptr[i]);
+ }
}
\ No newline at end of file
diff --git a/main/dap_configuration.h b/main/dap_configuration.h
new file mode 100644
index 0000000..07298cf
--- /dev/null
+++ b/main/dap_configuration.h
@@ -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
diff --git a/main/main.c b/main/main.c
index f70a663..a8c3e85 100644
--- a/main/main.c
+++ b/main/main.c
@@ -1,142 +1,142 @@
-/* BSD Socket API Example
-
- This example code is in the Public Domain (or CC0 licensed, at your option.)
-
- Unless required by applicable law or agreed to in writing, this
- software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied.
-*/
-#include
-#include
-#include
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "freertos/event_groups.h"
-#include "esp_system.h"
-#include "esp_wifi.h"
-#include "esp_event_loop.h"
-#include "esp_log.h"
-#include "nvs_flash.h"
-
-#include "lwip/err.h"
-#include "lwip/sockets.h"
-#include "lwip/sys.h"
-#include
-
-#include "tcp_server.h"
-#include "timer.h"
-#include "wifi_configuration.h"
-
-
-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 : %s\r\n", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
- break;
- case SYSTEM_EVENT_STA_DISCONNECTED:
- os_printf("Disconnect reason : %d\r\n", info->disconnected.reason);
- if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT)
- {
- /*Switch to 802.11 bgn mode */
- esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N);
- }
- esp_wifi_connect();
- xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT);
-#ifdef CONFIG_EXAMPLE_IPV6
- xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT);
-#endif
- break;
- case SYSTEM_EVENT_AP_STA_GOT_IP6:
-#ifdef CONFIG_EXAMPLE_IPV6
- xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT);
- os_printf("SYSTEM_EVENT_STA_GOT_IP6\r\n");
-
- char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip);
- os_printf("IPv6: %s\r\n", ip6);
-#endif
- default:
- break;
- }
- return ESP_OK;
-}
-
-static void initialise_wifi(void)
-{
- tcpip_adapter_init();
- wifi_event_group = xEventGroupCreate();
-
- ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
- wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
- ESP_ERROR_CHECK(esp_wifi_init(&cfg));
- ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
- wifi_config_t wifi_config = {
- .sta = {
- .ssid = WIFI_SSID,
- .password = WIFI_PASS,
- },
- };
- os_printf("Setting WiFi configuration SSID %s...\r\n", wifi_config.sta.ssid);
- ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
- ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
- ESP_ERROR_CHECK(esp_wifi_start());
-}
-
-static void wait_for_ip()
-{
-#ifdef CONFIG_EXAMPLE_IPV6
- uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT;
-#else
- uint32_t bits = IPV4_GOTIP_BIT;
-#endif
-
- os_printf("Waiting for AP connection...\r\n");
- xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY);
- os_printf("Connected to AP\r\n");
-}
-
-
-void app_main()
-{
- ESP_ERROR_CHECK(nvs_flash_init());
- initialise_wifi();
- wait_for_ip();
- DAP_Setup(); // DAP Setup
-
- xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL);
- xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 20, NULL);
- xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 22, &kDAPTaskHandle);
- // SWO Trace Task
- //xTaskCreate(SWO_Thread, "swo_task", 1024, NULL, 6, NULL);
- //xTaskCreate(usart_monitor_task, "uart_task", 512, NULL, 6, NULL);
-}
+/* BSD Socket API Example
+
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+ Unless required by applicable law or agreed to in writing, this
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied.
+*/
+#include
+#include
+#include
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+#include "esp_system.h"
+#include "esp_wifi.h"
+#include "esp_event_loop.h"
+#include "esp_log.h"
+#include "nvs_flash.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include
+
+#include "tcp_server.h"
+#include "timer.h"
+#include "wifi_configuration.h"
+
+
+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 : %s\r\n", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
+ break;
+ case SYSTEM_EVENT_STA_DISCONNECTED:
+ os_printf("Disconnect reason : %d\r\n", info->disconnected.reason);
+ if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT)
+ {
+ /*Switch to 802.11 bgn mode */
+ esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N);
+ }
+ esp_wifi_connect();
+ xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT);
+#ifdef CONFIG_EXAMPLE_IPV6
+ xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT);
+#endif
+ break;
+ case SYSTEM_EVENT_AP_STA_GOT_IP6:
+#ifdef CONFIG_EXAMPLE_IPV6
+ xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT);
+ os_printf("SYSTEM_EVENT_STA_GOT_IP6\r\n");
+
+ char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip);
+ os_printf("IPv6: %s\r\n", ip6);
+#endif
+ default:
+ break;
+ }
+ return ESP_OK;
+}
+
+static void initialise_wifi(void)
+{
+ tcpip_adapter_init();
+ wifi_event_group = xEventGroupCreate();
+
+ ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ ESP_ERROR_CHECK(esp_wifi_init(&cfg));
+ ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
+ wifi_config_t wifi_config = {
+ .sta = {
+ .ssid = WIFI_SSID,
+ .password = WIFI_PASS,
+ },
+ };
+ os_printf("Setting WiFi configuration SSID %s...\r\n", wifi_config.sta.ssid);
+ ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
+ ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
+ ESP_ERROR_CHECK(esp_wifi_start());
+}
+
+static void wait_for_ip()
+{
+#ifdef CONFIG_EXAMPLE_IPV6
+ uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT;
+#else
+ uint32_t bits = IPV4_GOTIP_BIT;
+#endif
+
+ os_printf("Waiting for AP connection...\r\n");
+ xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY);
+ os_printf("Connected to AP\r\n");
+}
+
+
+void app_main()
+{
+ ESP_ERROR_CHECK(nvs_flash_init());
+ initialise_wifi();
+ wait_for_ip();
+ DAP_Setup(); // DAP Setup
+
+ xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL);
+ xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 14, NULL);
+ xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 10, &kDAPTaskHandle);
+ // SWO Trace Task
+ //xTaskCreate(SWO_Thread, "swo_task", 1024, NULL, 6, NULL);
+ //xTaskCreate(usart_monitor_task, "uart_task", 512, NULL, 6, NULL);
+}
diff --git a/main/tcp_server.c b/main/tcp_server.c
index 8c481b1..8f85f6f 100644
--- a/main/tcp_server.c
+++ b/main/tcp_server.c
@@ -1,168 +1,181 @@
-/**
- * @file tcp_server.c
- * @brief Handle main tcp tasks
- * @version 0.1
- * @date 2020-01-22
- *
- * @copyright Copyright (c) 2020
- *
- */
-#include "tcp_server.h"
-
-#include
-#include
-#include
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "freertos/event_groups.h"
-#include "esp_system.h"
-#include "esp_wifi.h"
-#include "esp_event_loop.h"
-#include "esp_log.h"
-#include "nvs_flash.h"
-
-#include "lwip/err.h"
-#include "lwip/sockets.h"
-#include "lwip/sys.h"
-#include
-
-#include "wifi_configuration.h"
-#include "usbip_server.h"
-
-uint8_t kState = ACCEPTING;
-int kSock = -1;
-
-void tcp_server_task(void *pvParameters)
-{
- uint8_t tcp_rx_buffer[768];
- char addr_str[128];
- int addr_family;
- int ip_protocol;
-
- while (1)
- {
-
-#ifdef CONFIG_EXAMPLE_IPV4
- struct sockaddr_in destAddr;
- destAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- destAddr.sin_family = AF_INET;
- destAddr.sin_port = htons(PORT);
- addr_family = AF_INET;
- ip_protocol = IPPROTO_IP;
- inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
-#else // IPV6
- struct sockaddr_in6 destAddr;
- bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un));
- destAddr.sin6_family = AF_INET6;
- destAddr.sin6_port = htons(PORT);
- addr_family = AF_INET6;
- ip_protocol = IPPROTO_IPV6;
- inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
-#endif
-
- int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
- if (listen_sock < 0)
- {
- os_printf("Unable to create socket: errno %d\r\n", errno);
- break;
- }
- os_printf("Socket created\r\n");
-
- int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
- if (err != 0)
- {
- os_printf("Socket unable to bind: errno %d\r\n", errno);
- break;
- }
- os_printf("Socket binded\r\n");
-
- err = listen(listen_sock, 1);
- if (err != 0)
- {
- os_printf("Error occured during listen: errno %d\r\n", errno);
- break;
- }
- os_printf("Socket listening\r\n");
-
-#ifdef CONFIG_EXAMPLE_IPV6
- struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6
-#else
- struct sockaddr_in sourceAddr;
-#endif
- uint32_t addrLen = sizeof(sourceAddr);
- while (1)
- {
- kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
- if (kSock < 0)
- {
- os_printf("Unable to accept connection: errno %d\r\n", errno);
- break;
- }
- os_printf("Socket accepted\r\n");
-
- while (1)
- {
- int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 0);
- // Error occured during receiving
- if (len < 0)
- {
- os_printf("recv failed: errno %d\r\n", errno);
- break;
- }
- // Connection closed
- else if (len == 0)
- {
- os_printf("Connection closed\r\n");
- break;
- }
- // Data received
- else
- {
- // #ifdef CONFIG_EXAMPLE_IPV6
- // // Get the sender's ip address as string
- // if (sourceAddr.sin6_family == PF_INET)
- // {
- // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
- // }
- // else if (sourceAddr.sin6_family == PF_INET6)
- // {
- // inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
- // }
- // #else
- // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
- // #endif
-
- switch (kState)
- {
- case ACCEPTING:
- kState = ATTACHING;
-
- case ATTACHING:
- attach(tcp_rx_buffer, len);
- break;
-
- case EMULATING:
- emulate(tcp_rx_buffer, len);
- break;
- default:
- os_printf("unkonw kstate!\r\n");
- }
- }
- }
- // kState = ACCEPTING;
- if (kSock != -1)
- {
- os_printf("Shutting down socket and restarting...\r\n");
- //shutdown(kSock, 0);
- close(kSock);
- if (kState == EMULATING)
- kState = ACCEPTING;
-
- //shutdown(listen_sock, 0);
- //close(listen_sock);
- //vTaskDelay(5);
- }
- }
- }
- vTaskDelete(NULL);
+/**
+ * @file tcp_server.c
+ * @brief Handle main tcp tasks
+ * @version 0.1
+ * @date 2020-01-22
+ *
+ * @copyright Copyright (c) 2020
+ *
+ */
+#include "tcp_server.h"
+
+#include
+#include
+#include
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+#include "esp_system.h"
+#include "esp_wifi.h"
+#include "esp_event_loop.h"
+#include "esp_log.h"
+#include "nvs_flash.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include
+
+#include "wifi_configuration.h"
+#include "usbip_server.h"
+
+extern TaskHandle_t kDAPTaskHandle;
+extern int kRestartDAPHandle;
+
+uint8_t kState = ACCEPTING;
+int kSock = -1;
+
+void tcp_server_task(void *pvParameters)
+{
+ uint8_t tcp_rx_buffer[1024];
+ char addr_str[128];
+ int addr_family;
+ int ip_protocol;
+
+ int on = 1;
+ while (1)
+ {
+
+#ifdef CONFIG_EXAMPLE_IPV4
+ struct sockaddr_in destAddr;
+ destAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ destAddr.sin_family = AF_INET;
+ destAddr.sin_port = htons(PORT);
+ addr_family = AF_INET;
+ ip_protocol = IPPROTO_IP;
+ inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
+#else // IPV6
+ struct sockaddr_in6 destAddr;
+ bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un));
+ destAddr.sin6_family = AF_INET6;
+ destAddr.sin6_port = htons(PORT);
+ addr_family = AF_INET6;
+ ip_protocol = IPPROTO_IPV6;
+ inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
+#endif
+
+ int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
+ if (listen_sock < 0)
+ {
+ os_printf("Unable to create socket: errno %d\r\n", errno);
+ break;
+ }
+ os_printf("Socket created\r\n");
+
+ setsockopt(listen_sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
+ setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on));
+
+ int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
+ if (err != 0)
+ {
+ os_printf("Socket unable to bind: errno %d\r\n", errno);
+ break;
+ }
+ os_printf("Socket binded\r\n");
+
+ err = listen(listen_sock, 1);
+ if (err != 0)
+ {
+ os_printf("Error occured during listen: errno %d\r\n", errno);
+ break;
+ }
+ os_printf("Socket listening\r\n");
+
+#ifdef CONFIG_EXAMPLE_IPV6
+ struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6
+#else
+ struct sockaddr_in sourceAddr;
+#endif
+ uint32_t addrLen = sizeof(sourceAddr);
+ while (1)
+ {
+ kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
+ if (kSock < 0)
+ {
+ os_printf("Unable to accept connection: errno %d\r\n", errno);
+ break;
+ }
+ setsockopt(kSock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
+ setsockopt(kSock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on));
+ os_printf("Socket accepted\r\n");
+
+ while (1)
+ {
+ int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 0);
+ // Error occured during receiving
+ if (len < 0)
+ {
+ os_printf("recv failed: errno %d\r\n", errno);
+ break;
+ }
+ // Connection closed
+ else if (len == 0)
+ {
+ os_printf("Connection closed\r\n");
+ break;
+ }
+ // Data received
+ else
+ {
+ // #ifdef CONFIG_EXAMPLE_IPV6
+ // // Get the sender's ip address as string
+ // if (sourceAddr.sin6_family == PF_INET)
+ // {
+ // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
+ // }
+ // else if (sourceAddr.sin6_family == PF_INET6)
+ // {
+ // inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
+ // }
+ // #else
+ // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
+ // #endif
+
+ switch (kState)
+ {
+ case ACCEPTING:
+ kState = ATTACHING;
+
+ case ATTACHING:
+ attach(tcp_rx_buffer, len);
+ break;
+
+ case EMULATING:
+ emulate(tcp_rx_buffer, len);
+ break;
+ default:
+ os_printf("unkonw kstate!\r\n");
+ }
+ }
+ }
+ // kState = ACCEPTING;
+ if (kSock != -1)
+ {
+ os_printf("Shutting down socket and restarting...\r\n");
+ //shutdown(kSock, 0);
+ close(kSock);
+ if (kState == EMULATING)
+ kState = ACCEPTING;
+
+ // Restart DAP Handle
+ kRestartDAPHandle = 1;
+ xTaskNotifyGive(kDAPTaskHandle);
+
+ //shutdown(listen_sock, 0);
+ //close(listen_sock);
+ //vTaskDelay(5);
+ }
+ }
+ }
+ vTaskDelete(NULL);
}
\ No newline at end of file
diff --git a/sdkconfig b/sdkconfig
index e20f324..c3b4568 100644
--- a/sdkconfig
+++ b/sdkconfig
@@ -123,8 +123,8 @@ CONFIG_TASK_WDT_PANIC=y
CONFIG_TASK_WDT_TIMEOUT_15N=y
CONFIG_TASK_WDT_TIMEOUT_S=15
CONFIG_RESET_REASON=y
-CONFIG_WIFI_PPT_TASKSTACK_SIZE=2048
-CONFIG_EVENT_LOOP_STACK_SIZE=2048
+CONFIG_WIFI_PPT_TASKSTACK_SIZE=4096
+CONFIG_EVENT_LOOP_STACK_SIZE=4096
# CONFIG_ESP8266_OTA_FROM_OLD is not set
# CONFIG_ESP8266_BOOT_COPY_APP is not set
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_AMPDU_RX_ENABLED is not set
# CONFIG_ESP8266_WIFI_AMSDU_ENABLED is not set
-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_RX_BUFFER_NUM=28
+CONFIG_ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM=8
+CONFIG_ESP8266_WIFI_RX_PKT_NUM=16
CONFIG_ESP8266_WIFI_TX_PKT_NUM=6
CONFIG_ESP8266_WIFI_NVS_ENABLED=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_MAXAGE=300
# 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_SET_SOLINGER_DEFAULT=y
CONFIG_ESP_UDP_SYNC_SEND=y
CONFIG_ESP_UDP_SYNC_RETRY_MAX=5
CONFIG_LWIP_MAX_SOCKETS=10
@@ -214,13 +213,13 @@ CONFIG_ESP_DNS=y
CONFIG_DNS_MAX_SERVERS=3
# CONFIG_LWIP_NETIF_LOOPBACK is not set
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_TCP_MAXRTX=12
CONFIG_TCP_SYNMAXRTX=6
CONFIG_TCP_MSS=1460
CONFIG_TCP_SND_BUF_DEFAULT=2920
-CONFIG_TCP_WND_DEFAULT=5840
+CONFIG_TCP_WND_DEFAULT=10240
CONFIG_TCP_RECVMBOX_SIZE=16
CONFIG_TCP_QUEUE_OOSEQ=y
CONFIG_TCP_OVERSIZE_MSS=y