0
0
Fork 0

feat: Try to use SPI to implement SWD protocol

This commit is contained in:
windowsair 2020-12-07 00:15:01 +08:00
parent 95e9ede1dd
commit a7165d69ab
14 changed files with 1273 additions and 765 deletions

1
.gitignore vendored
View File

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

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"
//************************************************************************************************** //**************************************************************************************************
/** /**
\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
@ -189,12 +191,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 +303,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 +370,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.pin[PIN_SWDIO].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_SWDIO); // 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.pin[PIN_TDO].driver = 0;
GPIO.enable_w1tc |= (0x1 << PIN_TDO); GPIO.enable_w1tc |= (0x1 << PIN_TDO);
@ -431,7 +448,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 +458,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 +487,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 +506,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 +524,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 +596,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 +621,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 +744,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 +760,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,175 @@ 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);
} }

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,268 +1,287 @@
/** /**
* @file DAP_handle.c * @file DAP_handle.c
* @brief Handle DAP packets and transaction push * @brief Handle DAP packets and transaction push
* @version 0.3 * @version 0.3
* @date 2020-02-04 first version * @date 2020-02-04 first version
* 2020-11-11 support WinUSB mode * 2020-11-11 support WinUSB mode
* *
* @copyright Copyright (c) 2020 * @copyright Copyright (c) 2020
* *
*/ */
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "usbip_server.h" #include "usbip_server.h"
#include "DAP_handle.h" #include "DAP_handle.h"
#include "DAP.h" #include "DAP.h"
#include "esp_libc.h" #include "esp_libc.h"
#include "USBd_config.h" #include "USBd_config.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/ringbuf.h" #include "freertos/ringbuf.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/sockets.h" #include "lwip/sockets.h"
#include "lwip/sys.h" #include "lwip/sys.h"
#include <lwip/netdb.h> #include <lwip/netdb.h>
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) ////TODO: Merge this
typedef struct #define DAP_PACKET_SIZE 255
{
uint32_t length; #if (USE_WINUSB == 1)
uint8_t buf[DAP_PACKET_SIZE]; typedef struct
} DAPPacetDataType; {
#else uint32_t length;
typedef struct uint8_t buf[DAP_PACKET_SIZE];
{ } DAPPacetDataType;
uint8_t buf[DAP_PACKET_SIZE]; #else
} DAPPacetDataType; typedef struct
#endif {
uint8_t buf[DAP_PACKET_SIZE];
} DAPPacetDataType;
#define DAP_HANDLE_SIZE (sizeof(DAPPacetDataType)) #endif
static DAPPacetDataType DAPDataProcessed;
static int dap_respond = 0; #define DAP_HANDLE_SIZE (sizeof(DAPPacetDataType))
static DAPPacetDataType DAPDataProcessed;
// SWO Trace static int dap_respond = 0;
static int swo_trace_respond = 0;
static uint8_t *swo_data_to_send;
static uint32_t num_swo_data; // SWO Trace
static int swo_trace_respond = 0;
static RingbufHandle_t dap_dataIN_handle = NULL; static uint8_t *swo_data_to_send;
static RingbufHandle_t dap_dataOUT_handle = NULL; static uint32_t num_swo_data;
static SemaphoreHandle_t data_response_mux = NULL;
static RingbufHandle_t dap_dataIN_handle = NULL;
static void unpack(void *data, int size); static RingbufHandle_t dap_dataOUT_handle = NULL;
static SemaphoreHandle_t data_response_mux = NULL;
void handle_dap_data_request(usbip_stage2_header *header, uint32_t length)
{ static void unpack(void *data, int size);
uint8_t *data_in = (uint8_t *)header;
data_in = &(data_in[sizeof(usbip_stage2_header)]); void handle_dap_data_request(usbip_stage2_header *header, uint32_t length)
// Point to the beginning of the URB packet {
uint8_t *data_in = (uint8_t *)header;
#if (USE_WINUSB == 1) data_in = &(data_in[sizeof(usbip_stage2_header)]);
send_stage2_submit(header, 0, 0); // Point to the beginning of the URB packet
// always send constant size buf -> cuz we don't care about the IN packet size #if (USE_WINUSB == 1)
// and to unify the style, we set aside the length of the section send_stage2_submit(header, 0, 0);
xRingbufferSend(dap_dataIN_handle, data_in - sizeof(uint32_t), DAP_HANDLE_SIZE, portMAX_DELAY);
xTaskNotifyGive(kDAPTaskHandle); // 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
#else xRingbufferSend(dap_dataIN_handle, data_in - sizeof(uint32_t), DAP_HANDLE_SIZE, portMAX_DELAY);
send_stage2_submit(header, 0, 0); xTaskNotifyGive(kDAPTaskHandle);
xRingbufferSend(dap_dataIN_handle, data_in, DAP_HANDLE_SIZE, portMAX_DELAY); #else
xTaskNotifyGive(kDAPTaskHandle); send_stage2_submit(header, 0, 0);
#endif xRingbufferSend(dap_dataIN_handle, data_in, DAP_HANDLE_SIZE, portMAX_DELAY);
xTaskNotifyGive(kDAPTaskHandle);
// dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out);
// //handle_dap_data_response(header); #endif
// send_stage2_submit(header, 0, 0);
} // dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out);
// //handle_dap_data_response(header);
void handle_dap_data_response(usbip_stage2_header *header) // send_stage2_submit(header, 0, 0);
{ }
return;
// int resLength = dap_respond & 0xFFFF; void handle_dap_data_response(usbip_stage2_header *header)
// if (resLength) {
// { return;
// int resLength = dap_respond & 0xFFFF;
// send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, resLength); // if (resLength)
// dap_respond = 0; // {
// }
// else // send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, resLength);
// { // dap_respond = 0;
// send_stage2_submit(header, 0, 0); // }
// } // else
} // {
// send_stage2_submit(header, 0, 0);
void handle_swo_trace_response(usbip_stage2_header *header) // }
{ }
// TODO:
send_stage2_submit(header, 0, 0); void handle_swo_trace_response(usbip_stage2_header *header)
return; {
// TODO:
if (swo_trace_respond) send_stage2_submit(header, 0, 0);
{ return;
swo_trace_respond = 0;
//send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, DAP_PACKET_SIZE); if (swo_trace_respond)
} {
else swo_trace_respond = 0;
{ //send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, DAP_PACKET_SIZE);
send_stage2_submit(header, 0, 0); }
} 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 Queue Transfer
{ // buf: pointer to buffer with data
swo_data_to_send = buf; // num: number of bytes to transfer
num_swo_data = num; void SWO_QueueTransfer(uint8_t *buf, uint32_t num)
swo_trace_respond = 1; {
} swo_data_to_send = buf;
num_swo_data = num;
// SWO Data Abort Transfer swo_trace_respond = 1;
void SWO_AbortTransfer(void) }
{
//USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U)); // SWO Data Abort Transfer
////TODO: unlink might be useful ... void SWO_AbortTransfer(void)
} {
//USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
void DAP_Thread(void *argument) ////TODO: unlink might be useful ...
{ }
dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF); void DAP_Thread(void *argument)
data_response_mux = xSemaphoreCreateMutex(); {
size_t packetSize; dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
int resLength; dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
DAPPacetDataType *item; data_response_mux = xSemaphoreCreateMutex();
size_t packetSize;
if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL || int resLength;
data_response_mux == NULL) DAPPacetDataType *item;
{
os_printf("Can not create DAP ringbuf/mux!\r\n"); if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL ||
vTaskDelete(NULL); data_response_mux == NULL)
} {
for (;;) os_printf("Can not create DAP ringbuf/mux!\r\n");
{ vTaskDelete(NULL);
}
while (1) for (;;)
{ {
ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
packetSize = 0; while (1)
item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize, {
(1 / portTICK_RATE_MS), DAP_HANDLE_SIZE); if (kRestartDAPHandle)
if (packetSize == 0) {
{ vRingbufferDelete(dap_dataIN_handle);
break; vRingbufferDelete(dap_dataOUT_handle);
} dap_dataIN_handle = dap_dataOUT_handle = NULL;
else if (packetSize < DAP_HANDLE_SIZE) dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
{ dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
os_printf("Wrong data in packet size:%d , data in remain: %d\r\n", packetSize, (int)xRingbufferGetMaxItemSize(dap_dataIN_handle)); if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL)
vRingbufferReturnItem(dap_dataIN_handle, (void *)item); {
break; os_printf("Can not create DAP ringbuf/mux!\r\n");
// This may not happen because there is a semaphore acquisition vTaskDelete(NULL);
} }
kRestartDAPHandle = 0;
if (item->buf[0] == ID_DAP_QueueCommands) }
{
item->buf[0] = ID_DAP_ExecuteCommands; ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
} packetSize = 0;
item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize,
resLength = DAP_ProcessCommand((uint8_t *)item->buf, (uint8_t *)DAPDataProcessed.buf); // use first 4 byte to save length (1 / portTICK_RATE_MS), DAP_HANDLE_SIZE);
resLength &= 0xFFFF; // res length in lower 16 bits if (packetSize == 0)
{
vRingbufferReturnItem(dap_dataIN_handle, (void *)item); // process done. break;
}
// now prepare to reply
#if (USE_WINUSB == 1) else if (packetSize < DAP_HANDLE_SIZE)
DAPDataProcessed.length = resLength; {
#endif os_printf("Wrong data in packet size:%d , data in remain: %d\r\n", packetSize, (int)xRingbufferGetMaxItemSize(dap_dataIN_handle));
xRingbufferSend(dap_dataOUT_handle, (void *)&DAPDataProcessed, DAP_HANDLE_SIZE, portMAX_DELAY); vRingbufferReturnItem(dap_dataIN_handle, (void *)item);
break;
if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE) // This may not happen because there is a semaphore acquisition
{ }
++dap_respond;
xSemaphoreGive(data_response_mux); 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
int fast_reply(uint8_t *buf, uint32_t length) resLength &= 0xFFFF; // res length in lower 16 bits
{
if (length == 48 && buf[3] == 1 && buf[15] == 1 && buf[19] == 1) vRingbufferReturnItem(dap_dataIN_handle, (void *)item); // process done.
{
if (dap_respond > 0) // now prepare to reply
{ #if (USE_WINUSB == 1)
DAPPacetDataType *item; DAPDataProcessed.length = resLength;
size_t packetSize = 0; #endif
item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize, xRingbufferSend(dap_dataOUT_handle, (void *)&DAPDataProcessed, DAP_HANDLE_SIZE, portMAX_DELAY);
(10 / portTICK_RATE_MS), DAP_HANDLE_SIZE);
if (packetSize == DAP_HANDLE_SIZE) if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
{ {
unpack((uint32_t *)buf, sizeof(usbip_stage2_header)); ++dap_respond;
xSemaphoreGive(data_response_mux);
#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 int fast_reply(uint8_t *buf, uint32_t length)
{
if (length == 48 && buf[3] == 1 && buf[15] == 1 && buf[19] == 1)
if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE) {
{ if (dap_respond > 0)
--dap_respond; {
xSemaphoreGive(data_response_mux); DAPPacetDataType *item;
} size_t packetSize = 0;
item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize,
vRingbufferReturnItem(dap_dataOUT_handle, (void *)item); (10 / portTICK_RATE_MS), DAP_HANDLE_SIZE);
return 1; if (packetSize == DAP_HANDLE_SIZE)
} {
else if (packetSize > 0) unpack((uint32_t *)buf, sizeof(usbip_stage2_header));
{
os_printf("Wrong data out packet size:%d!\r\n", packetSize); #if (USE_WINUSB == 1)
} uint32_t resLength = item->length;
////TODO: fast reply send_stage2_submit_data((usbip_stage2_header *)buf, 0, item->buf, resLength);
} #else
else send_stage2_submit_data((usbip_stage2_header *)buf, 0, item->buf, DAP_HANDLE_SIZE);
{ #endif
//// TODO: ep0 dir 0 ?
buf[0x3] = 0x3; // command
buf[0xF] = 0; // direction if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
buf[0x16] = 0; {
buf[0x17] = 0; --dap_respond;
buf[27] = 0; xSemaphoreGive(data_response_mux);
buf[39] = 0; }
send(kSock, buf, 48, 0);
return 1; vRingbufferReturnItem(dap_dataOUT_handle, (void *)item);
} return 1;
} }
return 0; else if (packetSize > 0)
} {
os_printf("Wrong data out packet size:%d!\r\n", packetSize);
static void unpack(void *data, int size) }
{ ////TODO: fast reply
// Ignore the setup field }
int sz = (size / sizeof(uint32_t)) - 2; else
uint32_t *ptr = (uint32_t *)data; {
//// TODO: ep0 dir 0 ?
for (int i = 0; i < sz; i++) buf[0x3] = 0x3; // command
{ buf[0xF] = 0; // direction
ptr[i] = ntohl(ptr[i]); 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]);
}
} }

View File

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

@ -1,168 +1,175 @@
/** /**
* @file tcp_server.c * @file tcp_server.c
* @brief Handle main tcp tasks * @brief Handle main tcp tasks
* @version 0.1 * @version 0.1
* @date 2020-01-22 * @date 2020-01-22
* *
* @copyright Copyright (c) 2020 * @copyright Copyright (c) 2020
* *
*/ */
#include "tcp_server.h" #include "tcp_server.h"
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <sys/param.h> #include <sys/param.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/event_groups.h" #include "freertos/event_groups.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "esp_event_loop.h" #include "esp_event_loop.h"
#include "esp_log.h" #include "esp_log.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/sockets.h" #include "lwip/sockets.h"
#include "lwip/sys.h" #include "lwip/sys.h"
#include <lwip/netdb.h> #include <lwip/netdb.h>
#include "wifi_configuration.h" #include "wifi_configuration.h"
#include "usbip_server.h" #include "usbip_server.h"
uint8_t kState = ACCEPTING; extern TaskHandle_t kDAPTaskHandle;
int kSock = -1; extern int kRestartDAPHandle;
void tcp_server_task(void *pvParameters) uint8_t kState = ACCEPTING;
{ int kSock = -1;
uint8_t tcp_rx_buffer[768];
char addr_str[128]; void tcp_server_task(void *pvParameters)
int addr_family; {
int ip_protocol; uint8_t tcp_rx_buffer[768];
char addr_str[128];
while (1) int addr_family;
{ int ip_protocol;
#ifdef CONFIG_EXAMPLE_IPV4 while (1)
struct sockaddr_in destAddr; {
destAddr.sin_addr.s_addr = htonl(INADDR_ANY);
destAddr.sin_family = AF_INET; #ifdef CONFIG_EXAMPLE_IPV4
destAddr.sin_port = htons(PORT); struct sockaddr_in destAddr;
addr_family = AF_INET; destAddr.sin_addr.s_addr = htonl(INADDR_ANY);
ip_protocol = IPPROTO_IP; destAddr.sin_family = AF_INET;
inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); destAddr.sin_port = htons(PORT);
#else // IPV6 addr_family = AF_INET;
struct sockaddr_in6 destAddr; ip_protocol = IPPROTO_IP;
bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un)); inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
destAddr.sin6_family = AF_INET6; #else // IPV6
destAddr.sin6_port = htons(PORT); struct sockaddr_in6 destAddr;
addr_family = AF_INET6; bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un));
ip_protocol = IPPROTO_IPV6; destAddr.sin6_family = AF_INET6;
inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); destAddr.sin6_port = htons(PORT);
#endif addr_family = AF_INET6;
ip_protocol = IPPROTO_IPV6;
int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol); inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
if (listen_sock < 0) #endif
{
os_printf("Unable to create socket: errno %d\r\n", errno); int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
break; if (listen_sock < 0)
} {
os_printf("Socket created\r\n"); os_printf("Unable to create socket: errno %d\r\n", errno);
break;
int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); }
if (err != 0) os_printf("Socket created\r\n");
{
os_printf("Socket unable to bind: errno %d\r\n", errno); int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
break; if (err != 0)
} {
os_printf("Socket binded\r\n"); os_printf("Socket unable to bind: errno %d\r\n", errno);
break;
err = listen(listen_sock, 1); }
if (err != 0) os_printf("Socket binded\r\n");
{
os_printf("Error occured during listen: errno %d\r\n", errno); err = listen(listen_sock, 1);
break; if (err != 0)
} {
os_printf("Socket listening\r\n"); os_printf("Error occured during listen: errno %d\r\n", errno);
break;
#ifdef CONFIG_EXAMPLE_IPV6 }
struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6 os_printf("Socket listening\r\n");
#else
struct sockaddr_in sourceAddr; #ifdef CONFIG_EXAMPLE_IPV6
#endif struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6
uint32_t addrLen = sizeof(sourceAddr); #else
while (1) struct sockaddr_in sourceAddr;
{ #endif
kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); uint32_t addrLen = sizeof(sourceAddr);
if (kSock < 0) while (1)
{ {
os_printf("Unable to accept connection: errno %d\r\n", errno); kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
break; if (kSock < 0)
} {
os_printf("Socket accepted\r\n"); os_printf("Unable to accept connection: errno %d\r\n", errno);
break;
while (1) }
{ os_printf("Socket accepted\r\n");
int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 0);
// Error occured during receiving while (1)
if (len < 0) {
{ int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 0);
os_printf("recv failed: errno %d\r\n", errno); // Error occured during receiving
break; if (len < 0)
} {
// Connection closed os_printf("recv failed: errno %d\r\n", errno);
else if (len == 0) break;
{ }
os_printf("Connection closed\r\n"); // Connection closed
break; else if (len == 0)
} {
// Data received os_printf("Connection closed\r\n");
else break;
{ }
// #ifdef CONFIG_EXAMPLE_IPV6 // Data received
// // Get the sender's ip address as string else
// if (sourceAddr.sin6_family == PF_INET) {
// { // #ifdef CONFIG_EXAMPLE_IPV6
// inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); // // Get the sender's ip address as string
// } // if (sourceAddr.sin6_family == PF_INET)
// else if (sourceAddr.sin6_family == PF_INET6) // {
// { // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
// inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); // }
// } // else if (sourceAddr.sin6_family == PF_INET6)
// #else // {
// inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); // inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
// #endif // }
// #else
switch (kState) // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
{ // #endif
case ACCEPTING:
kState = ATTACHING; switch (kState)
{
case ATTACHING: case ACCEPTING:
attach(tcp_rx_buffer, len); kState = ATTACHING;
break;
case ATTACHING:
case EMULATING: attach(tcp_rx_buffer, len);
emulate(tcp_rx_buffer, len); break;
break;
default: case EMULATING:
os_printf("unkonw kstate!\r\n"); 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"); // kState = ACCEPTING;
//shutdown(kSock, 0); if (kSock != -1)
close(kSock); {
if (kState == EMULATING) os_printf("Shutting down socket and restarting...\r\n");
kState = ACCEPTING; //shutdown(kSock, 0);
close(kSock);
//shutdown(listen_sock, 0); if (kState == EMULATING)
//close(listen_sock); kState = ACCEPTING;
//vTaskDelay(5);
} // Restart DAP Handle
} kRestartDAPHandle = 1;
} xTaskNotifyGive(kDAPTaskHandle);
vTaskDelete(NULL);
//shutdown(listen_sock, 0);
//close(listen_sock);
//vTaskDelay(5);
}
}
}
vTaskDelete(NULL);
} }