feat: Try to support SWO (Still Unavailable)
This commit is contained in:
parent
dc0ab3b547
commit
2863553018
|
@ -1,3 +1,4 @@
|
||||||
.vscode/
|
.vscode/
|
||||||
build/
|
build/
|
||||||
tmp/
|
tmp/
|
||||||
|
.history/
|
|
@ -30,6 +30,7 @@
|
||||||
* @author windowsair
|
* @author windowsair
|
||||||
* @brief Adaptation of GPIO and SPI pin
|
* @brief Adaptation of GPIO and SPI pin
|
||||||
* @change: 2021-2-10 Support GPIO and SPI
|
* @change: 2021-2-10 Support GPIO and SPI
|
||||||
|
* 2021-2-18 Try to support SWO
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @date 2021-2-10
|
* @date 2021-2-10
|
||||||
*
|
*
|
||||||
|
@ -46,7 +47,7 @@
|
||||||
#include "cmsis_compiler.h"
|
#include "cmsis_compiler.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "gpio_struct.h"
|
#include "gpio_struct.h"
|
||||||
#include "timer_struct.h"
|
#include "timer.h"
|
||||||
#include "esp8266/pin_mux_register.h"
|
#include "esp8266/pin_mux_register.h"
|
||||||
|
|
||||||
#include "gpio_op.h"
|
#include "gpio_op.h"
|
||||||
|
@ -118,9 +119,13 @@ This information includes:
|
||||||
/// setting can be reduced (valid range is 1 .. 255).
|
/// setting can be reduced (valid range is 1 .. 255).
|
||||||
#define DAP_PACKET_COUNT 255 ///< Specifies number of packets buffered.
|
#define DAP_PACKET_COUNT 255 ///< Specifies number of packets buffered.
|
||||||
|
|
||||||
|
/// Indicates that the SWO function(UART SWO & Streaming Trace) is available
|
||||||
|
#define SWO_FUNCTION_ENABLE 1 ///< SWO function: 1 = available, 0 = not available.
|
||||||
|
|
||||||
|
|
||||||
/// Indicate that UART Serial Wire Output (SWO) trace is available.
|
/// Indicate that UART Serial Wire Output (SWO) trace is available.
|
||||||
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
|
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
|
||||||
#define SWO_UART 0 ///< SWO UART: 1 = available, 0 = not available.
|
#define SWO_UART SWO_FUNCTION_ENABLE ///< SWO UART: 1 = available, 0 = not available.
|
||||||
|
|
||||||
/// Maximum SWO UART Baudrate.
|
/// Maximum SWO UART Baudrate.
|
||||||
#define SWO_UART_MAX_BAUDRATE (115200U * 40U) ///< SWO UART Maximum Baudrate in Hz.
|
#define SWO_UART_MAX_BAUDRATE (115200U * 40U) ///< SWO UART Maximum Baudrate in Hz.
|
||||||
|
@ -130,12 +135,14 @@ This information includes:
|
||||||
/// Indicate that Manchester Serial Wire Output (SWO) trace is available.
|
/// Indicate that Manchester Serial Wire Output (SWO) trace is available.
|
||||||
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
|
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
|
||||||
#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available.
|
#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available.
|
||||||
|
// (windowsair)Do not modify. Not support.
|
||||||
|
|
||||||
|
|
||||||
/// SWO Trace Buffer Size.
|
/// SWO Trace Buffer Size.
|
||||||
#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n).
|
#define SWO_BUFFER_SIZE 2048U ///< SWO Trace Buffer Size in bytes (must be 2^n).
|
||||||
|
|
||||||
/// SWO Streaming Trace.
|
/// SWO Streaming Trace.
|
||||||
#define SWO_STREAM 0 ///< SWO Streaming Trace: 1 = available, 0 = not available.
|
#define SWO_STREAM SWO_FUNCTION_ENABLE ///< SWO Streaming Trace: 1 = available, 0 = not available.
|
||||||
|
|
||||||
/// Clock frequency of the Test Domain Timer. Timer value is returned with \ref TIMESTAMP_GET.
|
/// Clock frequency of the Test Domain Timer. Timer value is returned with \ref TIMESTAMP_GET.
|
||||||
#define TIMESTAMP_CLOCK 5000000U ///< Timestamp clock in Hz (0 = timestamps not supported).
|
#define TIMESTAMP_CLOCK 5000000U ///< Timestamp clock in Hz (0 = timestamps not supported).
|
||||||
|
@ -160,7 +167,6 @@ This information includes:
|
||||||
*/
|
*/
|
||||||
__STATIC_INLINE uint8_t DAP_GetVendorString(char *str)
|
__STATIC_INLINE uint8_t DAP_GetVendorString(char *str)
|
||||||
{
|
{
|
||||||
////TODO: fill this
|
|
||||||
// In fact, Keil can get the corresponding information through USB
|
// In fact, Keil can get the corresponding information through USB
|
||||||
// without filling in this information.
|
// without filling in this information.
|
||||||
// (void)str;
|
// (void)str;
|
||||||
|
@ -648,8 +654,7 @@ default, the DWT timer is used. The frequency of this timer is configured with
|
||||||
*/
|
*/
|
||||||
__STATIC_INLINE uint32_t TIMESTAMP_GET(void)
|
__STATIC_INLINE uint32_t TIMESTAMP_GET(void)
|
||||||
{
|
{
|
||||||
// FRC1 is a 23-bit countdown timer
|
return get_timer_count();
|
||||||
return (0x7FFFFF - (frc1.count.data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
|
|
@ -273,8 +273,8 @@ extern void SWO_TransferComplete (void);
|
||||||
extern uint32_t UART_SWO_Mode (uint32_t enable);
|
extern uint32_t UART_SWO_Mode (uint32_t enable);
|
||||||
extern uint32_t UART_SWO_Baudrate (uint32_t baudrate);
|
extern uint32_t UART_SWO_Baudrate (uint32_t baudrate);
|
||||||
extern uint32_t UART_SWO_Control (uint32_t active);
|
extern uint32_t UART_SWO_Control (uint32_t active);
|
||||||
extern void UART_SWO_Capture (uint8_t *buf, uint32_t num);
|
// extern void UART_SWO_Capture (uint8_t *buf, uint32_t num);
|
||||||
extern uint32_t UART_SWO_GetCount (void);
|
// extern uint32_t UART_SWO_GetCount (void);
|
||||||
|
|
||||||
extern uint32_t Manchester_SWO_Mode (uint32_t enable);
|
extern uint32_t Manchester_SWO_Mode (uint32_t enable);
|
||||||
extern uint32_t Manchester_SWO_Baudrate (uint32_t baudrate);
|
extern uint32_t Manchester_SWO_Baudrate (uint32_t baudrate);
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef __SWO_H__
|
||||||
|
#define __SWO_H__
|
||||||
|
|
||||||
|
typedef void * EventGroupHandle_t;
|
||||||
|
|
||||||
|
// event group bits
|
||||||
|
#define SWO_GOT_DATA 0x00000001
|
||||||
|
#define UART_GOT_DATA 0x00000002
|
||||||
|
#define SWO_ERROR_TIME_OUT 0x00000004
|
||||||
|
|
||||||
|
extern EventGroupHandle_t kSwoThreadEventGroup;
|
||||||
|
extern volatile uint8_t kSwoTransferBusy;
|
||||||
|
|
||||||
|
|
||||||
|
void SetTraceError(uint8_t flag); // Use in the uart handler
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* @brief Made some simple modifications to the official UART
|
* @brief Made some simple modifications to the official UART
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
|
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
@ -28,6 +28,13 @@ extern "C" {
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
|
// SWO modify
|
||||||
|
extern volatile uint32_t kSWO_read_index;
|
||||||
|
extern volatile uint32_t kSWO_read_num;
|
||||||
|
extern volatile uint8_t kSWO_uart_notify_enable;
|
||||||
|
extern SemaphoreHandle_t kSWO_read_mux;
|
||||||
|
|
||||||
#define UART_FIFO_LEN (128) /*!< Length of the hardware FIFO buffers */
|
#define UART_FIFO_LEN (128) /*!< Length of the hardware FIFO buffers */
|
||||||
#define UART_INTR_MASK 0x1ff /*!< Mask of all UART interrupts */
|
#define UART_INTR_MASK 0x1ff /*!< Mask of all UART interrupts */
|
||||||
|
@ -428,7 +435,7 @@ esp_err_t my_uart_intr_config(uart_port_t uart_num, uart_intr_config_t *uart_int
|
||||||
* @param uart_queue UART event queue handle (out param). On success, a new queue handle is written here to provide
|
* @param uart_queue UART event queue handle (out param). On success, a new queue handle is written here to provide
|
||||||
* access to UART events. If set to NULL, driver will not use an event queue.
|
* access to UART events. If set to NULL, driver will not use an event queue.
|
||||||
* @param no_use Invalid parameters, just to fit some modules.
|
* @param no_use Invalid parameters, just to fit some modules.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK Success
|
* - ESP_OK Success
|
||||||
* - ESP_ERR_INVALID_ARG Parameter error
|
* - ESP_ERR_INVALID_ARG Parameter error
|
||||||
|
@ -558,6 +565,30 @@ esp_err_t my_uart_get_buffered_data_len(uart_port_t uart_num, size_t *size);
|
||||||
*/
|
*/
|
||||||
esp_err_t my_uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh);
|
esp_err_t my_uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Asynchronously read bytes to swo buffer
|
||||||
|
* @note This function only serves as a notification,
|
||||||
|
* and will initiate a callback when the buffer reaches the length since we modify the uart
|
||||||
|
* @param index buffer index to read
|
||||||
|
* @param length data length
|
||||||
|
* @return esp_err_t
|
||||||
|
* - ESP_OK Success
|
||||||
|
* - ESP_FAIL There are still unfinished requests
|
||||||
|
*/
|
||||||
|
esp_err_t my_uart_read_bytes_async_swo(uint32_t index, uint32_t length);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART get RX ring buffer cached data length
|
||||||
|
* @note This function is basically equivalent to \ref my_uart_get_buffered_data_len
|
||||||
|
* @param uart_num UART port number.
|
||||||
|
*
|
||||||
|
* @return data length
|
||||||
|
*/
|
||||||
|
int my_uart_get_rx_buffered_data_len(uart_port_t uart_num);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
/**
|
/**
|
||||||
* @brief Modify this file to fit esp8266 Uart
|
* @file SWO.c
|
||||||
*
|
* @author windowsair
|
||||||
|
* @brief SWO support
|
||||||
|
* @change: 2021-02-17: Add basic functions
|
||||||
|
* @version 0.2
|
||||||
|
*
|
||||||
|
* @date 2021-02-17
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -37,15 +45,11 @@
|
||||||
#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 "uart_modify.h"
|
#include "uart_modify.h"
|
||||||
|
#include "swo.h"
|
||||||
|
|
||||||
|
EventGroupHandle_t kSwoThreadEventGroup;
|
||||||
EventGroupHandle_t kSWO_Thread_event_group;
|
|
||||||
EventGroupHandle_t kUART_Monitoe_event_group;
|
|
||||||
#define SWO_GOT_DATA BIT0
|
|
||||||
#define SWO_ERROR_TIME_OUT BIT1
|
|
||||||
|
|
||||||
#define UART_GOT_DATA BIT0
|
|
||||||
|
|
||||||
|
|
||||||
#if (SWO_STREAM != 0)
|
#if (SWO_STREAM != 0)
|
||||||
|
@ -61,14 +65,14 @@ EventGroupHandle_t kUART_Monitoe_event_group;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// use in baudrate setting
|
||||||
static uint8_t USART_Ready = 0U;
|
static uint8_t USART_Ready = 0U;
|
||||||
|
|
||||||
#endif /* (SWO_UART != 0) */
|
#endif /* (SWO_UART != 0) */
|
||||||
|
|
||||||
#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
|
#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
|
||||||
|
|
||||||
#define SWO_STREAM_TIMEOUT (50 / portTICK_RATE_MS) /* Stream timeout in ms */
|
#define SWO_STREAM_TIMEOUT pdMS_TO_TICKS(50) /* Stream timeout in ms */
|
||||||
|
|
||||||
#define USB_BLOCK_SIZE 512U /* USB Block Size */
|
#define USB_BLOCK_SIZE 512U /* USB Block Size */
|
||||||
#define TRACE_BLOCK_SIZE 64U /* Trace Block Size (2^n: 32...512) */
|
#define TRACE_BLOCK_SIZE 64U /* Trace Block Size (2^n: 32...512) */
|
||||||
|
@ -81,7 +85,7 @@ static uint8_t TraceError[2] = {0U, 0U}; /* Trace Error flags (banked) */
|
||||||
static uint8_t TraceError_n = 0U; /* Active Trace Error bank */
|
static uint8_t TraceError_n = 0U; /* Active Trace Error bank */
|
||||||
|
|
||||||
// Trace Buffer
|
// Trace Buffer
|
||||||
static uint8_t TraceBuf[SWO_BUFFER_SIZE]; /* Trace Buffer (must be 2^n) */
|
static uint8_t kSwoTraceBuf[SWO_BUFFER_SIZE]; /* Trace Buffer (must be 2^n) */
|
||||||
static volatile uint32_t TraceIndexI = 0U; /* Incoming Trace Index */
|
static volatile uint32_t TraceIndexI = 0U; /* Incoming Trace Index */
|
||||||
static volatile uint32_t TraceIndexO = 0U; /* Outgoing Trace Index */
|
static volatile uint32_t TraceIndexO = 0U; /* Outgoing Trace Index */
|
||||||
static volatile uint8_t TraceUpdate; /* Trace Update Flag */
|
static volatile uint8_t TraceUpdate; /* Trace Update Flag */
|
||||||
|
@ -101,105 +105,35 @@ static void ClearTrace(void);
|
||||||
static void ResumeTrace(void);
|
static void ResumeTrace(void);
|
||||||
static uint32_t GetTraceCount(void);
|
static uint32_t GetTraceCount(void);
|
||||||
static uint8_t GetTraceStatus(void);
|
static uint8_t GetTraceStatus(void);
|
||||||
void SetTraceError(uint8_t flag);
|
|
||||||
|
|
||||||
#if (SWO_STREAM != 0)
|
#if (SWO_STREAM != 0)
|
||||||
|
|
||||||
static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */
|
volatile uint8_t kSwoTransferBusy = 0U; /* Transfer Busy Flag */
|
||||||
static uint32_t TransferSize; /* Current Transfer Size */
|
static uint32_t TransferSize; /* Current Transfer Size */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (SWO_UART != 0)
|
#if (SWO_UART != 0)
|
||||||
|
|
||||||
|
|
||||||
void usart_monitor_task(void *argument)
|
|
||||||
{
|
|
||||||
uint32_t index_i;
|
|
||||||
uint32_t index_o;
|
|
||||||
uint32_t count;
|
|
||||||
uint32_t num;
|
|
||||||
uint32_t flags;
|
|
||||||
|
|
||||||
kUART_Monitoe_event_group = xEventGroupCreate();
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
flags = xEventGroupWaitBits(kUART_Monitoe_event_group, UART_GOT_DATA,
|
|
||||||
pdTRUE, pdFALSE, portMAX_DELAY);
|
|
||||||
if (flags & UART_GOT_DATA)
|
|
||||||
{
|
|
||||||
#if (TIMESTAMP_CLOCK != 0U)
|
|
||||||
TraceTimestamp.tick = TIMESTAMP_GET();
|
|
||||||
#endif
|
|
||||||
index_o = TraceIndexO;
|
|
||||||
index_i = TraceIndexI;
|
|
||||||
index_i += TraceBlockSize;
|
|
||||||
TraceIndexI = index_i;
|
|
||||||
#if (TIMESTAMP_CLOCK != 0U)
|
|
||||||
TraceTimestamp.index = index_i;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
num = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U));
|
|
||||||
// num is the number of bytes we need to read
|
|
||||||
// (to achieve the size of TRACE_BLOCK_SIZE)
|
|
||||||
count = index_i - index_o;
|
|
||||||
// Amount of data that has not been processed yet
|
|
||||||
|
|
||||||
// (SWO_BUFFER_SIZE-num): the remaining usable length of the buffer after reading this data
|
|
||||||
if (count <= (SWO_BUFFER_SIZE - num))
|
|
||||||
{
|
|
||||||
index_i &= SWO_BUFFER_SIZE - 1U;
|
|
||||||
TraceBlockSize = num;
|
|
||||||
my_uart_read_bytes(USART_PORT, &TraceBuf[index_i], num, 20 / portTICK_RATE_MS);
|
|
||||||
//pUSART->Receive(&TraceBuf[index_i], num);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Not enough buffers
|
|
||||||
TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED;
|
|
||||||
}
|
|
||||||
TraceUpdate = 1U;
|
|
||||||
#if (SWO_STREAM != 0)
|
|
||||||
if (TraceTransport == 2U)
|
|
||||||
{
|
|
||||||
if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U))))
|
|
||||||
{
|
|
||||||
xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (event & ARM_USART_EVENT_RX_OVERFLOW)
|
|
||||||
// {
|
|
||||||
// SetTraceError(DAP_SWO_BUFFER_OVERRUN);
|
|
||||||
// }
|
|
||||||
// if (event & (ARM_USART_EVENT_RX_BREAK |
|
|
||||||
// ARM_USART_EVENT_RX_FRAMING_ERROR |
|
|
||||||
// ARM_USART_EVENT_RX_PARITY_ERROR))
|
|
||||||
// {
|
|
||||||
// SetTraceError(DAP_SWO_STREAM_ERROR);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable or disable UART SWO Mode
|
// Enable or disable UART SWO Mode
|
||||||
// enable: enable flag
|
// enable: enable flag
|
||||||
// return: 1 - Success, 0 - Error
|
// return: 1 - Success, 0 - Error
|
||||||
__WEAK uint32_t UART_SWO_Mode(uint32_t enable)
|
uint32_t UART_SWO_Mode(uint32_t enable)
|
||||||
{
|
{
|
||||||
int32_t status;
|
int32_t status;
|
||||||
|
|
||||||
USART_Ready = 0U;
|
USART_Ready = 0U;
|
||||||
uart_config_t uart_config = {
|
uart_config_t uart_config = {
|
||||||
.baud_rate = 115200,
|
.baud_rate = 74880,
|
||||||
.data_bits = UART_DATA_8_BITS,
|
.data_bits = UART_DATA_8_BITS,
|
||||||
.parity = UART_PARITY_DISABLE,
|
.parity = UART_PARITY_DISABLE,
|
||||||
.stop_bits = UART_STOP_BITS_1,
|
.stop_bits = UART_STOP_BITS_1,
|
||||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
|
||||||
my_uart_param_config(USART_PORT, &uart_config);
|
my_uart_param_config(USART_PORT, &uart_config); // register setting
|
||||||
|
|
||||||
#define BUF_SIZE (1024)
|
#define BUF_SIZE (1024)
|
||||||
my_uart_driver_install(USART_PORT, BUF_SIZE, 0, 0, NULL, 0);
|
//// TODO: remove this
|
||||||
|
|
||||||
if (enable != 0U)
|
if (enable != 0U)
|
||||||
{
|
{
|
||||||
|
@ -207,6 +141,7 @@ __WEAK uint32_t UART_SWO_Mode(uint32_t enable)
|
||||||
status = my_uart_driver_install(USART_PORT, BUF_SIZE, 0, 0, NULL, 0);
|
status = my_uart_driver_install(USART_PORT, BUF_SIZE, 0, 0, NULL, 0);
|
||||||
if (status != ESP_OK)
|
if (status != ESP_OK)
|
||||||
{
|
{
|
||||||
|
my_uart_driver_delete(USART_PORT);
|
||||||
return (0U);
|
return (0U);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,6 +149,7 @@ __WEAK uint32_t UART_SWO_Mode(uint32_t enable)
|
||||||
{
|
{
|
||||||
my_uart_driver_delete(USART_PORT);
|
my_uart_driver_delete(USART_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (1U);
|
return (1U);
|
||||||
|
|
||||||
|
|
||||||
|
@ -222,11 +158,12 @@ __WEAK uint32_t UART_SWO_Mode(uint32_t enable)
|
||||||
// Configure UART SWO Baudrate
|
// Configure UART SWO Baudrate
|
||||||
// baudrate: requested baudrate
|
// baudrate: requested baudrate
|
||||||
// return: actual baudrate or 0 when not configured
|
// return: actual baudrate or 0 when not configured
|
||||||
__WEAK uint32_t UART_SWO_Baudrate(uint32_t baudrate)
|
uint32_t UART_SWO_Baudrate(uint32_t baudrate)
|
||||||
{
|
{
|
||||||
int32_t status;
|
//// TODO: There may be bugs.
|
||||||
|
//int32_t status;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
uint32_t num;
|
uint32_t remain_trace_block_size;
|
||||||
|
|
||||||
if (baudrate > SWO_UART_MAX_BAUDRATE)
|
if (baudrate > SWO_UART_MAX_BAUDRATE)
|
||||||
{
|
{
|
||||||
|
@ -235,10 +172,8 @@ __WEAK uint32_t UART_SWO_Baudrate(uint32_t baudrate)
|
||||||
|
|
||||||
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
|
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
TraceIndexI += my_uart_get_rx_buffered_data_len(USART_PORT);
|
||||||
my_uart_get_buffered_data_len(USART_PORT, &len);
|
|
||||||
my_uart_flush(USART_PORT);
|
my_uart_flush(USART_PORT);
|
||||||
TraceIndexI += len;
|
|
||||||
// pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
// pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
||||||
// if (pUSART->GetStatus().rx_busy)
|
// if (pUSART->GetStatus().rx_busy)
|
||||||
// {
|
// {
|
||||||
|
@ -248,29 +183,21 @@ __WEAK uint32_t UART_SWO_Baudrate(uint32_t baudrate)
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
status = my_uart_set_baudrate(USART_PORT, baudrate);
|
my_uart_set_baudrate(USART_PORT, baudrate);
|
||||||
|
|
||||||
|
USART_Ready = 1U;
|
||||||
|
|
||||||
if (status == ESP_OK)
|
|
||||||
{
|
|
||||||
USART_Ready = 1U;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
USART_Ready = 0U;
|
|
||||||
return (0U);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
|
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
|
||||||
{
|
{
|
||||||
if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U)
|
if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U)
|
||||||
{
|
{
|
||||||
index = TraceIndexI & (SWO_BUFFER_SIZE - 1U);
|
index = TraceIndexI & (SWO_BUFFER_SIZE - 1U); // TraceIndexI % SWO_BUFFER_SIZE
|
||||||
num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U));
|
remain_trace_block_size = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U)); // index % TRACE_BLOCK_SIZE
|
||||||
TraceBlockSize = num;
|
TraceBlockSize = remain_trace_block_size;
|
||||||
//pUSART->Receive(&TraceBuf[index], num);
|
//pUSART->Receive(&kSwoTraceBuf[index], num);
|
||||||
my_uart_read_bytes(USART_PORT, &TraceBuf[index], num, 20 / portTICK_RATE_MS);
|
my_uart_read_bytes_async_swo(index, remain_trace_block_size);
|
||||||
}
|
}
|
||||||
//pUSART->Control(ARM_USART_CONTROL_RX, 1U); ////TODO:
|
//pUSART->Control(ARM_USART_CONTROL_RX, 1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (baudrate);
|
return (baudrate);
|
||||||
|
@ -279,7 +206,7 @@ __WEAK uint32_t UART_SWO_Baudrate(uint32_t baudrate)
|
||||||
// Control UART SWO Capture
|
// Control UART SWO Capture
|
||||||
// active: active flag
|
// active: active flag
|
||||||
// return: 1 - Success, 0 - Error
|
// return: 1 - Success, 0 - Error
|
||||||
__WEAK uint32_t UART_SWO_Control(uint32_t active)
|
uint32_t UART_SWO_Control(uint32_t active)
|
||||||
{
|
{
|
||||||
int32_t status;
|
int32_t status;
|
||||||
|
|
||||||
|
@ -290,7 +217,8 @@ __WEAK uint32_t UART_SWO_Control(uint32_t active)
|
||||||
return (0U);
|
return (0U);
|
||||||
}
|
}
|
||||||
TraceBlockSize = 1U;
|
TraceBlockSize = 1U;
|
||||||
status = my_uart_read_bytes(USART_PORT, &TraceBuf[0], 1U, 20 / portTICK_RATE_MS);
|
status = my_uart_read_bytes_async_swo(0, 1U);
|
||||||
|
|
||||||
if (status == ESP_FAIL)
|
if (status == ESP_FAIL)
|
||||||
{
|
{
|
||||||
return (0U);
|
return (0U);
|
||||||
|
@ -299,14 +227,13 @@ __WEAK uint32_t UART_SWO_Control(uint32_t active)
|
||||||
// if (status != ARM_DRIVER_OK)
|
// if (status != ARM_DRIVER_OK)
|
||||||
// {
|
// {
|
||||||
// return (0U);
|
// return (0U);
|
||||||
// } ////TODO:
|
// }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
// no active
|
||||||
my_uart_get_buffered_data_len(USART_PORT, &len);
|
TraceIndexI += my_uart_get_rx_buffered_data_len(USART_PORT);
|
||||||
my_uart_flush(USART_PORT);
|
my_uart_flush(USART_PORT);
|
||||||
TraceIndexI += len;
|
|
||||||
// pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
// pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
||||||
// if (pUSART->GetStatus().rx_busy)
|
// if (pUSART->GetStatus().rx_busy)
|
||||||
// {
|
// {
|
||||||
|
@ -318,20 +245,19 @@ __WEAK uint32_t UART_SWO_Control(uint32_t active)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start UART SWO Capture
|
// Start UART SWO Capture
|
||||||
// buf: pointer to buffer for capturing
|
// index: trace buffer index to read
|
||||||
// num: number of bytes to capture
|
// num: number of bytes to capture
|
||||||
__WEAK void UART_SWO_Capture(uint8_t *buf, uint32_t num)
|
static void UART_SWO_Capture(uint32_t index, uint32_t num)
|
||||||
{
|
{
|
||||||
TraceBlockSize = num;
|
TraceBlockSize = num;
|
||||||
my_uart_read_bytes(USART_PORT, buf, num, 20 / portTICK_RATE_MS);
|
my_uart_read_bytes_async_swo(index, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get UART SWO Pending Trace Count
|
// Get UART SWO Pending Trace Count
|
||||||
// return: number of pending trace data bytes
|
// return: number of pending trace data bytes
|
||||||
__WEAK uint32_t UART_SWO_GetCount(void)
|
static uint32_t UART_SWO_GetCount(void)
|
||||||
{
|
{
|
||||||
uint32_t count;
|
//// TODO: There may be bugs.
|
||||||
|
|
||||||
// if (pUSART->GetStatus().rx_busy)
|
// if (pUSART->GetStatus().rx_busy)
|
||||||
// {
|
// {
|
||||||
// count = pUSART->GetRxCount();
|
// count = pUSART->GetRxCount();
|
||||||
|
@ -340,65 +266,31 @@ __WEAK uint32_t UART_SWO_GetCount(void)
|
||||||
// {
|
// {
|
||||||
// count = 0U;
|
// count = 0U;
|
||||||
// }
|
// }
|
||||||
my_uart_get_buffered_data_len(USART_PORT, &count);
|
return my_uart_get_rx_buffered_data_len(USART_PORT);
|
||||||
return (count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* (SWO_UART != 0) */
|
#endif /* (SWO_UART != 0) */
|
||||||
|
|
||||||
#if (SWO_MANCHESTER != 0)
|
|
||||||
|
|
||||||
// Enable or disable Manchester SWO Mode
|
|
||||||
// enable: enable flag
|
|
||||||
// return: 1 - Success, 0 - Error
|
|
||||||
__WEAK uint32_t Manchester_SWO_Mode(uint32_t enable)
|
|
||||||
{
|
|
||||||
return (0U);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure Manchester SWO Baudrate
|
//
|
||||||
// baudrate: requested baudrate
|
// Trace status helper functions
|
||||||
// return: actual baudrate or 0 when not configured
|
//
|
||||||
__WEAK uint32_t Manchester_SWO_Baudrate(uint32_t baudrate)
|
|
||||||
{
|
|
||||||
return (0U);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Control Manchester SWO Capture
|
|
||||||
// active: active flag
|
|
||||||
// return: 1 - Success, 0 - Error
|
|
||||||
__WEAK uint32_t Manchester_SWO_Control(uint32_t active)
|
|
||||||
{
|
|
||||||
return (0U);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start Manchester SWO Capture
|
|
||||||
// buf: pointer to buffer for capturing
|
|
||||||
// num: number of bytes to capture
|
|
||||||
__WEAK void Manchester_SWO_Capture(uint8_t *buf, uint32_t num)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Manchester SWO Pending Trace Count
|
|
||||||
// return: number of pending trace data bytes
|
|
||||||
__WEAK uint32_t Manchester_SWO_GetCount(void)
|
|
||||||
{
|
|
||||||
return (0U);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* (SWO_MANCHESTER != 0) */
|
|
||||||
|
|
||||||
// Clear Trace Errors and Data
|
// Clear Trace Errors and Data
|
||||||
static void ClearTrace(void)
|
static void ClearTrace(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if (SWO_STREAM != 0)
|
#if (SWO_STREAM != 0)
|
||||||
if (TraceTransport == 2U)
|
if (TraceTransport == 2U) // Indicates that we use WinUSB for transfer.
|
||||||
{
|
{
|
||||||
if (TransferBusy != 0U)
|
if (kSwoTransferBusy != 0U)
|
||||||
{
|
{
|
||||||
SWO_AbortTransfer();
|
// Unfortunately, we cannot abort the transmission
|
||||||
TransferBusy = 0U;
|
// SWO_AbortTransfer();
|
||||||
|
kSwoTransferBusy = 0U;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -430,18 +322,10 @@ static void ResumeTrace(void)
|
||||||
index_i &= SWO_BUFFER_SIZE - 1U;
|
index_i &= SWO_BUFFER_SIZE - 1U;
|
||||||
switch (TraceMode)
|
switch (TraceMode)
|
||||||
{
|
{
|
||||||
#if (SWO_UART != 0)
|
|
||||||
case DAP_SWO_UART:
|
case DAP_SWO_UART:
|
||||||
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
|
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
|
||||||
UART_SWO_Capture(&TraceBuf[index_i], 1U);
|
UART_SWO_Capture(index_i, 1U);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if (SWO_MANCHESTER != 0)
|
|
||||||
case DAP_SWO_MANCHESTER:
|
|
||||||
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
|
|
||||||
Manchester_SWO_Capture(&TraceBuf[index_i], 1U);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -463,20 +347,15 @@ static uint32_t GetTraceCount(void)
|
||||||
count = TraceIndexI - TraceIndexO;
|
count = TraceIndexI - TraceIndexO;
|
||||||
switch (TraceMode)
|
switch (TraceMode)
|
||||||
{
|
{
|
||||||
#if (SWO_UART != 0)
|
|
||||||
case DAP_SWO_UART:
|
case DAP_SWO_UART:
|
||||||
count += UART_SWO_GetCount();
|
count += UART_SWO_GetCount();
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if (SWO_MANCHESTER != 0)
|
|
||||||
case DAP_SWO_MANCHESTER:
|
|
||||||
count += Manchester_SWO_GetCount();
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
} while (TraceUpdate != 0U);
|
} while (TraceUpdate != 0U);
|
||||||
|
// Synchronously wait for the data to complete
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -541,14 +420,7 @@ uint32_t SWO_Transport(const uint8_t *request, uint8_t *response)
|
||||||
result = 0U;
|
result = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != 0U)
|
*response = result ? DAP_OK : DAP_ERROR;
|
||||||
{
|
|
||||||
*response = DAP_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*response = DAP_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((1U << 16) | 1U);
|
return ((1U << 16) | 1U);
|
||||||
}
|
}
|
||||||
|
@ -565,6 +437,7 @@ uint32_t SWO_Mode(const uint8_t *request, uint8_t *response)
|
||||||
|
|
||||||
mode = *request;
|
mode = *request;
|
||||||
|
|
||||||
|
// disable swo mode
|
||||||
switch (TraceMode)
|
switch (TraceMode)
|
||||||
{
|
{
|
||||||
#if (SWO_UART != 0)
|
#if (SWO_UART != 0)
|
||||||
|
@ -572,11 +445,7 @@ uint32_t SWO_Mode(const uint8_t *request, uint8_t *response)
|
||||||
UART_SWO_Mode(0U);
|
UART_SWO_Mode(0U);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if (SWO_MANCHESTER != 0)
|
|
||||||
case DAP_SWO_MANCHESTER:
|
|
||||||
Manchester_SWO_Mode(0U);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -591,34 +460,18 @@ uint32_t SWO_Mode(const uint8_t *request, uint8_t *response)
|
||||||
result = UART_SWO_Mode(1U);
|
result = UART_SWO_Mode(1U);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if (SWO_MANCHESTER != 0)
|
|
||||||
case DAP_SWO_MANCHESTER:
|
|
||||||
result = Manchester_SWO_Mode(1U);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
result = 0U;
|
result = 0U;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (result != 0U)
|
|
||||||
{
|
// DAP_SWO_OFF -> has error
|
||||||
TraceMode = mode;
|
TraceMode = result ? mode : DAP_SWO_OFF;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TraceMode = DAP_SWO_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
TraceStatus = 0U;
|
TraceStatus = 0U;
|
||||||
|
|
||||||
if (result != 0U)
|
*response = result ? DAP_OK : DAP_ERROR;
|
||||||
{
|
|
||||||
*response = DAP_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*response = DAP_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((1U << 16) | 1U);
|
return ((1U << 16) | 1U);
|
||||||
}
|
}
|
||||||
|
@ -644,11 +497,7 @@ uint32_t SWO_Baudrate(const uint8_t *request, uint8_t *response)
|
||||||
baudrate = UART_SWO_Baudrate(baudrate);
|
baudrate = UART_SWO_Baudrate(baudrate);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if (SWO_MANCHESTER != 0)
|
|
||||||
case DAP_SWO_MANCHESTER:
|
|
||||||
baudrate = Manchester_SWO_Baudrate(baudrate);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
baudrate = 0U;
|
baudrate = 0U;
|
||||||
break;
|
break;
|
||||||
|
@ -681,7 +530,9 @@ uint32_t SWO_Control(const uint8_t *request, uint8_t *response)
|
||||||
|
|
||||||
if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE))
|
if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE))
|
||||||
{
|
{
|
||||||
if (active)
|
// active status: request != now status
|
||||||
|
|
||||||
|
if (active) // request: active
|
||||||
{
|
{
|
||||||
ClearTrace();
|
ClearTrace();
|
||||||
}
|
}
|
||||||
|
@ -692,39 +543,32 @@ uint32_t SWO_Control(const uint8_t *request, uint8_t *response)
|
||||||
result = UART_SWO_Control(active);
|
result = UART_SWO_Control(active);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if (SWO_MANCHESTER != 0)
|
|
||||||
case DAP_SWO_MANCHESTER:
|
|
||||||
result = Manchester_SWO_Control(active);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
result = 0U;
|
result = 0U;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != 0U)
|
if (result != 0U)
|
||||||
{
|
{
|
||||||
|
// success done
|
||||||
TraceStatus = active;
|
TraceStatus = active;
|
||||||
#if (SWO_STREAM != 0)
|
#if (SWO_STREAM != 0)
|
||||||
if (TraceTransport == 2U)
|
if (TraceTransport == 2U) // Indicates that we use WinUSB for transfer.
|
||||||
{
|
{
|
||||||
xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
|
xEventGroupSetBits(kSwoThreadEventGroup, SWO_GOT_DATA);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// request: active but already actived
|
||||||
result = 1U;
|
result = 1U;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != 0U)
|
|
||||||
{
|
*response = result ? DAP_OK : DAP_ERROR;
|
||||||
*response = DAP_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*response = DAP_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((1U << 16) | 1U);
|
return ((1U << 16) | 1U);
|
||||||
}
|
}
|
||||||
|
@ -793,6 +637,7 @@ uint32_t SWO_ExtendedStatus(const uint8_t *request, uint8_t *response)
|
||||||
TraceUpdate = 0U;
|
TraceUpdate = 0U;
|
||||||
index = TraceTimestamp.index;
|
index = TraceTimestamp.index;
|
||||||
tick = TraceTimestamp.tick;
|
tick = TraceTimestamp.tick;
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
} while (TraceUpdate != 0U);
|
} while (TraceUpdate != 0U);
|
||||||
*response++ = (uint8_t)(index >> 0);
|
*response++ = (uint8_t)(index >> 0);
|
||||||
*response++ = (uint8_t)(index >> 8);
|
*response++ = (uint8_t)(index >> 8);
|
||||||
|
@ -824,6 +669,8 @@ uint32_t SWO_Data(const uint8_t *request, uint8_t *response)
|
||||||
status = GetTraceStatus();
|
status = GetTraceStatus();
|
||||||
count = GetTraceCount();
|
count = GetTraceCount();
|
||||||
|
|
||||||
|
// transport 1: use DAP SWO command
|
||||||
|
// transport 2: WinUSB
|
||||||
if (TraceTransport == 1U)
|
if (TraceTransport == 1U)
|
||||||
{
|
{
|
||||||
n = (uint32_t)(*(request + 0) << 0) |
|
n = (uint32_t)(*(request + 0) << 0) |
|
||||||
|
@ -839,6 +686,7 @@ uint32_t SWO_Data(const uint8_t *request, uint8_t *response)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// if use winusb, then nothing to do.
|
||||||
count = 0U;
|
count = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,7 +700,7 @@ uint32_t SWO_Data(const uint8_t *request, uint8_t *response)
|
||||||
for (i = index, n = count; n; n--)
|
for (i = index, n = count; n; n--)
|
||||||
{
|
{
|
||||||
i &= SWO_BUFFER_SIZE - 1U;
|
i &= SWO_BUFFER_SIZE - 1U;
|
||||||
*response++ = TraceBuf[i++];
|
*response++ = kSwoTraceBuf[i++];
|
||||||
}
|
}
|
||||||
TraceIndexO = index + count;
|
TraceIndexO = index + count;
|
||||||
ResumeTrace();
|
ResumeTrace();
|
||||||
|
@ -867,78 +715,171 @@ uint32_t SWO_Data(const uint8_t *request, uint8_t *response)
|
||||||
void SWO_TransferComplete(void)
|
void SWO_TransferComplete(void)
|
||||||
{
|
{
|
||||||
TraceIndexO += TransferSize;
|
TraceIndexO += TransferSize;
|
||||||
TransferBusy = 0U;
|
kSwoTransferBusy = 0U;
|
||||||
ResumeTrace();
|
ResumeTrace();
|
||||||
xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
|
xEventGroupSetBits(kSwoThreadEventGroup, SWO_GOT_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SWO Thread
|
// SWO Thread
|
||||||
void SWO_Thread(void *argument)
|
void SWO_Thread()
|
||||||
{
|
{
|
||||||
uint32_t timeout;
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
uint32_t i, n;
|
uint32_t i, n;
|
||||||
(void)argument;
|
|
||||||
|
|
||||||
timeout = portMAX_DELAY;
|
uint32_t index_i;
|
||||||
|
uint32_t index_o;
|
||||||
kSWO_Thread_event_group = xEventGroupCreate();
|
uint32_t remain_trace_block_size;
|
||||||
|
|
||||||
|
TickType_t timeout = portMAX_DELAY;
|
||||||
|
|
||||||
|
kSwoThreadEventGroup = xEventGroupCreate();
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
flags = xEventGroupWaitBits(kSWO_Thread_event_group, SWO_GOT_DATA | SWO_ERROR_TIME_OUT,
|
/*
|
||||||
|
Here, our event group handles two main types of events:
|
||||||
|
1. `SWO_GOT_DATA` : The SWO package may be ready to send.
|
||||||
|
2. `UART_GOT_DATA` : The uart transfer event is complete and we can start reading.
|
||||||
|
|
||||||
|
Note that the `SWO_ERROR_TIME_OUT` flag is only used for internal processing, only when the status is
|
||||||
|
inactive can it be set.
|
||||||
|
|
||||||
|
We deal with uart events first.
|
||||||
|
Currently, SWO events are always handled.
|
||||||
|
*/
|
||||||
|
flags = xEventGroupWaitBits(kSwoThreadEventGroup, SWO_GOT_DATA | UART_GOT_DATA | SWO_ERROR_TIME_OUT,
|
||||||
pdTRUE, pdFALSE, timeout);
|
pdTRUE, pdFALSE, timeout);
|
||||||
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
|
|
||||||
|
if (!(flags & UART_GOT_DATA) && !(flags & SWO_GOT_DATA))
|
||||||
{
|
{
|
||||||
timeout = SWO_STREAM_TIMEOUT;
|
if (TraceMode != DAP_SWO_OFF && my_uart_get_rx_buffered_data_len(USART_PORT) >= kSWO_read_num)
|
||||||
|
{
|
||||||
|
flags = UART_GOT_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & UART_GOT_DATA)
|
||||||
|
{
|
||||||
|
// The data is still in the uart buffer,
|
||||||
|
// and the data in the uart needs to be read into the SWO buffer
|
||||||
|
my_uart_read_bytes(USART_PORT, &kSwoTraceBuf[kSWO_read_index], kSWO_read_num, pdMS_TO_TICKS(20));
|
||||||
|
|
||||||
|
|
||||||
|
index_o = TraceIndexO;
|
||||||
|
|
||||||
|
TraceIndexI += TraceBlockSize;
|
||||||
|
index_i = TraceIndexI;
|
||||||
|
|
||||||
|
#if (TIMESTAMP_CLOCK != 0U)
|
||||||
|
TraceTimestamp.tick = TIMESTAMP_GET();
|
||||||
|
TraceTimestamp.index = index_i;
|
||||||
|
#endif
|
||||||
|
remain_trace_block_size = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U));
|
||||||
|
// remain_trace_block_size is the number of bytes we need to read
|
||||||
|
// (to achieve the size of TRACE_BLOCK_SIZE)
|
||||||
|
count = index_i - index_o;
|
||||||
|
// Amount of data that has not been processed yet
|
||||||
|
|
||||||
|
// (SWO_BUFFER_SIZE-num): the remaining usable length of the buffer after reading this data
|
||||||
|
if (count <= (SWO_BUFFER_SIZE - remain_trace_block_size))
|
||||||
|
{
|
||||||
|
// index_i % 4096
|
||||||
|
index_i &= SWO_BUFFER_SIZE - 1U;
|
||||||
|
TraceBlockSize = remain_trace_block_size;
|
||||||
|
my_uart_read_bytes_async_swo(index_i, remain_trace_block_size);
|
||||||
|
//pUSART->Receive(&kSwoTraceBuf[index_i], num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not enough buffers
|
||||||
|
TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED;
|
||||||
|
}
|
||||||
|
TraceUpdate = 1U;
|
||||||
|
#if (SWO_STREAM != 0)
|
||||||
|
if (TraceTransport == 2U) // Indicates that we use WinUSB for transfer.
|
||||||
|
{
|
||||||
|
// unsent length >= remaining length of the USB block
|
||||||
|
//// TODO: may be we can remove this
|
||||||
|
if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U))))
|
||||||
|
{
|
||||||
|
flags = SWO_GOT_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// xEventGroupClearBits
|
||||||
|
|
||||||
|
/*
|
||||||
|
`SWO_GOT_DATA` may be set in the following situations:
|
||||||
|
- The SWO status requested by `SWD_contorl` is different from the current SWO status.
|
||||||
|
- When `SWO_TransferComplete` is called, and there may be potentially unsent data in the buffer.
|
||||||
|
- monitor task believes we need to send data that is already long enough.
|
||||||
|
|
||||||
|
Note: The processing of the following code segment will always be executed,
|
||||||
|
and should be ensured to be stable enough.
|
||||||
|
|
||||||
|
|
||||||
|
TODO: The time interval for executing the code is not guaranteed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!(TraceStatus & DAP_SWO_CAPTURE_ACTIVE))
|
||||||
|
{
|
||||||
|
flags = SWO_ERROR_TIME_OUT;
|
||||||
|
timeout = portMAX_DELAY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timeout = portMAX_DELAY;
|
timeout = pdMS_TO_TICKS(150);
|
||||||
flags = SWO_ERROR_TIME_OUT;
|
|
||||||
}
|
}
|
||||||
if (TransferBusy == 0U)
|
|
||||||
|
if (kSwoTransferBusy)
|
||||||
{
|
{
|
||||||
count = GetTraceCount();
|
continue;
|
||||||
if (count != 0U)
|
}
|
||||||
|
|
||||||
|
count = GetTraceCount();
|
||||||
|
if (count != 0U)
|
||||||
|
{
|
||||||
|
index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
|
||||||
|
n = SWO_BUFFER_SIZE - index;
|
||||||
|
if (count > n)
|
||||||
{
|
{
|
||||||
index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
|
count = n;
|
||||||
n = SWO_BUFFER_SIZE - index;
|
}
|
||||||
if (count > n)
|
if ((flags & SWO_ERROR_TIME_OUT) == 0)
|
||||||
|
{
|
||||||
|
i = index & (USB_BLOCK_SIZE - 1U);
|
||||||
|
if (i == 0U)
|
||||||
{
|
{
|
||||||
count = n;
|
count &= ~(USB_BLOCK_SIZE - 1U); // Take down to the nearest number that is a multiple of USB_BLOCK_SIZE
|
||||||
}
|
}
|
||||||
if ((flags & SWO_ERROR_TIME_OUT) == 0)
|
else
|
||||||
{
|
{
|
||||||
i = index & (USB_BLOCK_SIZE - 1U);
|
n = USB_BLOCK_SIZE - i;
|
||||||
if (i == 0U)
|
if (count >= n)
|
||||||
{
|
{
|
||||||
count &= ~(USB_BLOCK_SIZE - 1U);
|
count = n; // The number of bytes to be sent exceeds the remain USB block size.
|
||||||
// Take down to the nearest number that is a multiple of USB_BLOCK_SIZE
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n = USB_BLOCK_SIZE - i;
|
count = 0U; // Haven't received a full USB block yet.
|
||||||
if (count >= n)
|
|
||||||
{
|
|
||||||
count = n;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
count = 0U;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count != 0U)
|
}
|
||||||
{
|
// Notify that there is data available for transmission
|
||||||
TransferSize = count;
|
if (count != 0U)
|
||||||
TransferBusy = 1U;
|
{
|
||||||
SWO_QueueTransfer(&TraceBuf[index], count); //through USB
|
TransferSize = count;
|
||||||
}
|
kSwoTransferBusy = 1U;
|
||||||
|
SWO_QueueTransfer(&kSwoTraceBuf[index], count); // through USB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For all exceptions, we have handled them directly in the interrupt handlers.
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* (SWO_STREAM != 0) */
|
#endif /* (SWO_STREAM != 0) */
|
||||||
|
|
|
@ -218,6 +218,7 @@ void SWD_Sequence_SPI (uint32_t info, const uint8_t *swdo, uint8_t *swdi) {
|
||||||
// data: DATA[31:0]
|
// data: DATA[31:0]
|
||||||
// return: ACK[2:0]
|
// return: ACK[2:0]
|
||||||
static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) {
|
static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) {
|
||||||
|
//// FIXME: overrun detection
|
||||||
// SPI transfer mode does not require operations such as PIN_DELAY
|
// SPI transfer mode does not require operations such as PIN_DELAY
|
||||||
uint8_t ack;
|
uint8_t ack;
|
||||||
// uint32_t bit;
|
// uint32_t bit;
|
||||||
|
@ -355,7 +356,6 @@ static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) {
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//// FIXME: bug
|
|
||||||
/* Protocol error */
|
/* Protocol error */
|
||||||
DAP_SPI_Disable();
|
DAP_SPI_Disable();
|
||||||
PIN_SWDIO_TMS_SET();
|
PIN_SWDIO_TMS_SET();
|
||||||
|
|
|
@ -83,7 +83,7 @@ void DAP_SPI_WriteBits(const uint8_t count, const uint8_t *buf)
|
||||||
// Start transmission
|
// Start transmission
|
||||||
DAP_SPI.cmd.usr = 1;
|
DAP_SPI.cmd.usr = 1;
|
||||||
// Wait for sending to complete
|
// Wait for sending to complete
|
||||||
while (DAP_SPI.cmd.usr);
|
while (DAP_SPI.cmd.usr) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ void DAP_SPI_ReadBits(const uint8_t count, uint8_t *buf) {
|
||||||
// Start transmission
|
// Start transmission
|
||||||
DAP_SPI.cmd.usr = 1;
|
DAP_SPI.cmd.usr = 1;
|
||||||
// Wait for reading to complete
|
// Wait for reading to complete
|
||||||
while (DAP_SPI.cmd.usr);
|
while (DAP_SPI.cmd.usr) continue;
|
||||||
|
|
||||||
data_buf[0] = DAP_SPI.data_buf[0];
|
data_buf[0] = DAP_SPI.data_buf[0];
|
||||||
data_buf[1] = DAP_SPI.data_buf[1];
|
data_buf[1] = DAP_SPI.data_buf[1];
|
||||||
|
@ -148,7 +148,7 @@ __FORCEINLINE void DAP_SPI_Send_Header(const uint8_t packetHeaderData, uint8_t *
|
||||||
// Start transmission
|
// Start transmission
|
||||||
DAP_SPI.cmd.usr = 1;
|
DAP_SPI.cmd.usr = 1;
|
||||||
// Wait for sending to complete
|
// Wait for sending to complete
|
||||||
while (DAP_SPI.cmd.usr);
|
while (DAP_SPI.cmd.usr) continue;
|
||||||
|
|
||||||
dataBuf = DAP_SPI.data_buf[0];
|
dataBuf = DAP_SPI.data_buf[0];
|
||||||
*ack = (dataBuf >> 1) & 0b111;
|
*ack = (dataBuf >> 1) & 0b111;
|
||||||
|
@ -175,7 +175,7 @@ __FORCEINLINE void DAP_SPI_Read_Data(uint32_t *resData, uint8_t *resParity)
|
||||||
// Start transmission
|
// Start transmission
|
||||||
DAP_SPI.cmd.usr = 1;
|
DAP_SPI.cmd.usr = 1;
|
||||||
// Wait for sending to complete
|
// Wait for sending to complete
|
||||||
while (DAP_SPI.cmd.usr);
|
while (DAP_SPI.cmd.usr) continue;
|
||||||
|
|
||||||
pU32Data[0] = DAP_SPI.data_buf[0];
|
pU32Data[0] = DAP_SPI.data_buf[0];
|
||||||
pU32Data[1] = DAP_SPI.data_buf[1];
|
pU32Data[1] = DAP_SPI.data_buf[1];
|
||||||
|
@ -204,7 +204,7 @@ __FORCEINLINE void DAP_SPI_Write_Data(uint32_t data, uint8_t parity)
|
||||||
// Start transmission
|
// Start transmission
|
||||||
DAP_SPI.cmd.usr = 1;
|
DAP_SPI.cmd.usr = 1;
|
||||||
// Wait for sending to complete
|
// Wait for sending to complete
|
||||||
while (DAP_SPI.cmd.usr);
|
while (DAP_SPI.cmd.usr) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -221,8 +221,10 @@ __FORCEINLINE void DAP_SPI_Generate_Cycle(uint8_t num)
|
||||||
|
|
||||||
DAP_SPI.data_buf[0] = 0x00000000U;
|
DAP_SPI.data_buf[0] = 0x00000000U;
|
||||||
|
|
||||||
|
// Start transmission
|
||||||
DAP_SPI.cmd.usr = 1;
|
DAP_SPI.cmd.usr = 1;
|
||||||
while (DAP_SPI.cmd.usr);
|
// Wait for sending to complete
|
||||||
|
while (DAP_SPI.cmd.usr) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -239,8 +241,10 @@ __FORCEINLINE void DAP_SPI_Protocol_Error_Read()
|
||||||
DAP_SPI.data_buf[0] = 0xFFFFFFFFU;
|
DAP_SPI.data_buf[0] = 0xFFFFFFFFU;
|
||||||
DAP_SPI.data_buf[1] = 0xFFFFFFFFU;
|
DAP_SPI.data_buf[1] = 0xFFFFFFFFU;
|
||||||
|
|
||||||
|
// Start transmission
|
||||||
DAP_SPI.cmd.usr = 1;
|
DAP_SPI.cmd.usr = 1;
|
||||||
while (DAP_SPI.cmd.usr);
|
// Wait for sending to complete
|
||||||
|
while (DAP_SPI.cmd.usr) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -257,6 +261,8 @@ __FORCEINLINE void DAP_SPI_Protocol_Error_Write()
|
||||||
DAP_SPI.data_buf[0] = 0xFFFFFFFFU;
|
DAP_SPI.data_buf[0] = 0xFFFFFFFFU;
|
||||||
DAP_SPI.data_buf[1] = 0xFFFFFFFFU;
|
DAP_SPI.data_buf[1] = 0xFFFFFFFFU;
|
||||||
|
|
||||||
|
// Start transmission
|
||||||
DAP_SPI.cmd.usr = 1;
|
DAP_SPI.cmd.usr = 1;
|
||||||
while (DAP_SPI.cmd.usr);
|
// Wait for sending to complete
|
||||||
|
while (DAP_SPI.cmd.usr) continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* @brief Made some simple modifications to the official UART
|
* @brief Made some simple modifications to the official UART
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
|
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
@ -41,6 +41,7 @@
|
||||||
#include "rom/ets_sys.h"
|
#include "rom/ets_sys.h"
|
||||||
|
|
||||||
#include "uart_modify.h"
|
#include "uart_modify.h"
|
||||||
|
#include "swo.h"
|
||||||
#include "driver/uart_select.h"
|
#include "driver/uart_select.h"
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() taskYIELD()
|
#define portYIELD_FROM_ISR() taskYIELD()
|
||||||
|
@ -70,6 +71,11 @@ typedef struct
|
||||||
} tx_data;
|
} tx_data;
|
||||||
} uart_tx_data_t;
|
} uart_tx_data_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// read:
|
||||||
|
// hardware FIFO -> `rx_data_buf` -> `rx_ring_buf` -> user buf
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uart_port_t uart_num; /*!< UART port number*/
|
uart_port_t uart_num; /*!< UART port number*/
|
||||||
|
@ -118,18 +124,21 @@ typedef struct
|
||||||
static uart_isr_func_t uart_isr_func[UART_NUM_MAX];
|
static uart_isr_func_t uart_isr_func[UART_NUM_MAX];
|
||||||
|
|
||||||
// SWO modify
|
// SWO modify
|
||||||
extern EventGroupHandle_t kUART_Monitoe_event_group;
|
|
||||||
#define UART_GOT_DATA BIT0
|
|
||||||
extern void SetTraceError(uint8_t flag);
|
|
||||||
#define DAP_SWO_CAPTURE_ACTIVE (1U << 0)
|
#define DAP_SWO_CAPTURE_ACTIVE (1U << 0)
|
||||||
#define DAP_SWO_CAPTURE_PAUSED (1U << 1)
|
#define DAP_SWO_CAPTURE_PAUSED (1U << 1)
|
||||||
#define DAP_SWO_STREAM_ERROR (1U << 6)
|
#define DAP_SWO_STREAM_ERROR (1U << 6)
|
||||||
#define DAP_SWO_BUFFER_OVERRUN (1U << 7)
|
#define DAP_SWO_BUFFER_OVERRUN (1U << 7)
|
||||||
//
|
|
||||||
|
// non thread safe
|
||||||
|
volatile uint32_t kSWO_read_index = 0;
|
||||||
|
volatile uint32_t kSWO_read_num = 0;
|
||||||
|
volatile uint8_t kSWO_uart_notify_enable = 1;
|
||||||
|
SemaphoreHandle_t kSWO_read_mux = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
esp_err_t my_uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit)
|
esp_err_t my_uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
|
||||||
UART_CHECK((data_bit < UART_DATA_BITS_MAX), "data bit error", ESP_ERR_INVALID_ARG);
|
UART_CHECK((data_bit < UART_DATA_BITS_MAX), "data bit error", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
UART_ENTER_CRITICAL();
|
UART_ENTER_CRITICAL();
|
||||||
|
@ -140,7 +149,6 @@ esp_err_t my_uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_
|
||||||
|
|
||||||
esp_err_t my_uart_get_word_length(uart_port_t uart_num, uart_word_length_t *data_bit)
|
esp_err_t my_uart_get_word_length(uart_port_t uart_num, uart_word_length_t *data_bit)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
|
||||||
UART_CHECK((data_bit), "empty pointer", ESP_FAIL);
|
UART_CHECK((data_bit), "empty pointer", ESP_FAIL);
|
||||||
|
|
||||||
*(data_bit) = UART[uart_num]->conf0.bit_num;
|
*(data_bit) = UART[uart_num]->conf0.bit_num;
|
||||||
|
@ -149,7 +157,6 @@ esp_err_t my_uart_get_word_length(uart_port_t uart_num, uart_word_length_t *data
|
||||||
|
|
||||||
esp_err_t my_uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit)
|
esp_err_t my_uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
|
||||||
UART_CHECK((stop_bit < UART_STOP_BITS_MAX), "stop bit error", ESP_ERR_INVALID_ARG);
|
UART_CHECK((stop_bit < UART_STOP_BITS_MAX), "stop bit error", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
UART_ENTER_CRITICAL();
|
UART_ENTER_CRITICAL();
|
||||||
|
@ -160,7 +167,6 @@ esp_err_t my_uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit)
|
||||||
|
|
||||||
esp_err_t my_uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t *stop_bit)
|
esp_err_t my_uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t *stop_bit)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
|
||||||
UART_CHECK((stop_bit), "empty pointer", ESP_FAIL);
|
UART_CHECK((stop_bit), "empty pointer", ESP_FAIL);
|
||||||
|
|
||||||
(*stop_bit) = UART[uart_num]->conf0.stop_bit_num;
|
(*stop_bit) = UART[uart_num]->conf0.stop_bit_num;
|
||||||
|
@ -169,7 +175,6 @@ esp_err_t my_uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t *stop_bit
|
||||||
|
|
||||||
esp_err_t my_uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode)
|
esp_err_t my_uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
|
||||||
UART_CHECK(((parity_mode == UART_PARITY_DISABLE) || (parity_mode == UART_PARITY_EVEN) || (parity_mode == UART_PARITY_ODD)),
|
UART_CHECK(((parity_mode == UART_PARITY_DISABLE) || (parity_mode == UART_PARITY_EVEN) || (parity_mode == UART_PARITY_ODD)),
|
||||||
"parity_mode error", ESP_ERR_INVALID_ARG);
|
"parity_mode error", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
|
@ -182,7 +187,6 @@ esp_err_t my_uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode)
|
||||||
|
|
||||||
esp_err_t my_uart_get_parity(uart_port_t uart_num, uart_parity_t *parity_mode)
|
esp_err_t my_uart_get_parity(uart_port_t uart_num, uart_parity_t *parity_mode)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
|
||||||
UART_CHECK((parity_mode), "empty pointer", ESP_ERR_INVALID_ARG);
|
UART_CHECK((parity_mode), "empty pointer", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
UART_ENTER_CRITICAL();
|
UART_ENTER_CRITICAL();
|
||||||
|
@ -209,8 +213,6 @@ esp_err_t my_uart_get_parity(uart_port_t uart_num, uart_parity_t *parity_mode)
|
||||||
|
|
||||||
esp_err_t my_uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate)
|
esp_err_t my_uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
|
||||||
|
|
||||||
UART_ENTER_CRITICAL();
|
UART_ENTER_CRITICAL();
|
||||||
UART[uart_num]->clk_div.val = (uint32_t)(UART_CLK_FREQ / baud_rate) & 0xFFFFF;
|
UART[uart_num]->clk_div.val = (uint32_t)(UART_CLK_FREQ / baud_rate) & 0xFFFFF;
|
||||||
UART_EXIT_CRITICAL();
|
UART_EXIT_CRITICAL();
|
||||||
|
@ -219,7 +221,6 @@ esp_err_t my_uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate)
|
||||||
|
|
||||||
esp_err_t my_uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate)
|
esp_err_t my_uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
|
||||||
UART_CHECK((baudrate), "empty pointer", ESP_ERR_INVALID_ARG);
|
UART_CHECK((baudrate), "empty pointer", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
(*baudrate) = (UART_CLK_FREQ / (UART[uart_num]->clk_div.val & 0xFFFFF));
|
(*baudrate) = (UART_CLK_FREQ / (UART[uart_num]->clk_div.val & 0xFFFFF));
|
||||||
|
@ -228,7 +229,6 @@ esp_err_t my_uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate)
|
||||||
|
|
||||||
esp_err_t my_uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask)
|
esp_err_t my_uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
|
||||||
UART_CHECK((((inverse_mask & ~UART_LINE_INV_MASK) == 0) || (inverse_mask == 0)), "inverse_mask error", ESP_ERR_INVALID_ARG);
|
UART_CHECK((((inverse_mask & ~UART_LINE_INV_MASK) == 0) || (inverse_mask == 0)), "inverse_mask error", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
UART_ENTER_CRITICAL();
|
UART_ENTER_CRITICAL();
|
||||||
|
@ -377,6 +377,7 @@ static esp_err_t uart_reset_rx_fifo(uart_port_t uart_num)
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear uart interrupts status.
|
||||||
esp_err_t my_uart_clear_intr_status(uart_port_t uart_num, uint32_t mask)
|
esp_err_t my_uart_clear_intr_status(uart_port_t uart_num, uint32_t mask)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
||||||
|
@ -387,6 +388,7 @@ esp_err_t my_uart_clear_intr_status(uart_port_t uart_num, uint32_t mask)
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set UART interrupt enable
|
||||||
esp_err_t my_uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask)
|
esp_err_t my_uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
||||||
|
@ -407,6 +409,9 @@ esp_err_t my_uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask)
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// helper function
|
||||||
|
|
||||||
esp_err_t my_uart_enable_rx_intr(uart_port_t uart_num)
|
esp_err_t my_uart_enable_rx_intr(uart_port_t uart_num)
|
||||||
{
|
{
|
||||||
return my_uart_enable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
|
return my_uart_enable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
|
||||||
|
@ -435,6 +440,9 @@ esp_err_t my_uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh)
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void uart_intr_service(void *arg)
|
static void uart_intr_service(void *arg)
|
||||||
{
|
{
|
||||||
// UART intr process
|
// UART intr process
|
||||||
|
@ -460,6 +468,7 @@ static void uart_intr_service(void *arg)
|
||||||
} while (++uart_num < UART_NUM_MAX);
|
} while (++uart_num < UART_NUM_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setting isr function
|
||||||
esp_err_t my_uart_isr_register(uart_port_t uart_num, void (*fn)(void *), void *arg)
|
esp_err_t my_uart_isr_register(uart_port_t uart_num, void (*fn)(void *), void *arg)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
||||||
|
@ -552,7 +561,7 @@ static void uart_rx_intr_handler_default(void *param)
|
||||||
uart_obj_t *p_uart = (uart_obj_t *)param;
|
uart_obj_t *p_uart = (uart_obj_t *)param;
|
||||||
uint8_t uart_num = p_uart->uart_num;
|
uint8_t uart_num = p_uart->uart_num;
|
||||||
uart_dev_t *uart_reg = UART[uart_num];
|
uart_dev_t *uart_reg = UART[uart_num];
|
||||||
int rx_fifo_len = uart_reg->status.rxfifo_cnt;
|
int rx_fifo_len = uart_reg->status.rxfifo_cnt;
|
||||||
uint8_t buf_idx = 0;
|
uint8_t buf_idx = 0;
|
||||||
uint32_t uart_intr_status = UART[uart_num]->int_st.val;
|
uint32_t uart_intr_status = UART[uart_num]->int_st.val;
|
||||||
uart_event_t uart_event;
|
uart_event_t uart_event;
|
||||||
|
@ -718,7 +727,17 @@ static void uart_rx_intr_handler_default(void *param)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p_uart->rx_buffered_len += p_uart->rx_stash_len;
|
p_uart->rx_buffered_len += p_uart->rx_stash_len;
|
||||||
xEventGroupSetBitsFromISR(kUART_Monitoe_event_group, UART_GOT_DATA, pdFALSE);
|
// SWO modify
|
||||||
|
if (kSWO_read_num && p_uart->rx_buffered_len >= kSWO_read_num)
|
||||||
|
{
|
||||||
|
if (kSWO_uart_notify_enable)
|
||||||
|
{
|
||||||
|
kSWO_uart_notify_enable = 0;
|
||||||
|
xEventGroupSetBitsFromISR(kSwoThreadEventGroup, UART_GOT_DATA, pdFALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notify = UART_SELECT_READ_NOTIF;
|
notify = UART_SELECT_READ_NOTIF;
|
||||||
|
@ -744,7 +763,7 @@ static void uart_rx_intr_handler_default(void *param)
|
||||||
// SWO modify
|
// SWO modify
|
||||||
// Unfortunately, Overflow occurs usually there is no flow control.
|
// Unfortunately, Overflow occurs usually there is no flow control.
|
||||||
// Although the overflow situation often occurs,
|
// Although the overflow situation often occurs,
|
||||||
// the buffer stability of the serial port is better,
|
// the buffer stability of the serial port is better,
|
||||||
// and there is basically no data loss.
|
// and there is basically no data loss.
|
||||||
////TODO: Can we get rid of this code?
|
////TODO: Can we get rid of this code?
|
||||||
SetTraceError(DAP_SWO_BUFFER_OVERRUN);
|
SetTraceError(DAP_SWO_BUFFER_OVERRUN);
|
||||||
|
@ -804,6 +823,7 @@ static void uart_rx_intr_handler_default(void *param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fill UART tx_fifo and return a number,
|
// Fill UART tx_fifo and return a number,
|
||||||
// This function by itself is not thread-safe, always call from within a muxed section.
|
// This function by itself is not thread-safe, always call from within a muxed section.
|
||||||
static int uart_fill_fifo(uart_port_t uart_num, const char *buffer, uint32_t len)
|
static int uart_fill_fifo(uart_port_t uart_num, const char *buffer, uint32_t len)
|
||||||
|
@ -904,6 +924,8 @@ int my_uart_write_bytes(uart_port_t uart_num, const char *src, size_t size)
|
||||||
return uart_tx_all(uart_num, src, size);
|
return uart_tx_all(uart_num, src, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return min(length, data length in ring buffer)
|
||||||
int my_uart_read_bytes(uart_port_t uart_num, uint8_t *buf, uint32_t length, TickType_t ticks_to_wait)
|
int my_uart_read_bytes(uart_port_t uart_num, uint8_t *buf, uint32_t length, TickType_t ticks_to_wait)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1));
|
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1));
|
||||||
|
@ -934,6 +956,7 @@ int my_uart_read_bytes(uart_port_t uart_num, uint8_t *buf, uint32_t length, Tick
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// nothing receive
|
||||||
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
|
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
|
||||||
return copy_len;
|
return copy_len;
|
||||||
}
|
}
|
||||||
|
@ -974,6 +997,15 @@ int my_uart_read_bytes(uart_port_t uart_num, uint8_t *buf, uint32_t length, Tick
|
||||||
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
|
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
|
||||||
UART_EXIT_CRITICAL();
|
UART_EXIT_CRITICAL();
|
||||||
my_uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
|
my_uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
|
||||||
|
// SWO modify
|
||||||
|
if (uart_num == 0 && kSWO_read_num && p_uart_obj[0]->rx_buffered_len >= kSWO_read_num)
|
||||||
|
{
|
||||||
|
if (kSWO_uart_notify_enable)
|
||||||
|
{
|
||||||
|
kSWO_uart_notify_enable = 0;
|
||||||
|
xEventGroupSetBitsFromISR(kSwoThreadEventGroup, UART_GOT_DATA, pdFALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -994,6 +1026,7 @@ esp_err_t my_uart_get_buffered_data_len(uart_port_t uart_num, size_t *size)
|
||||||
|
|
||||||
esp_err_t my_uart_flush(uart_port_t uart_num) __attribute__((alias("my_uart_flush_input")));
|
esp_err_t my_uart_flush(uart_port_t uart_num) __attribute__((alias("my_uart_flush_input")));
|
||||||
|
|
||||||
|
// flush RX buffer
|
||||||
esp_err_t my_uart_flush_input(uart_port_t uart_num)
|
esp_err_t my_uart_flush_input(uart_port_t uart_num)
|
||||||
{
|
{
|
||||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
||||||
|
@ -1051,6 +1084,15 @@ esp_err_t my_uart_flush_input(uart_port_t uart_num)
|
||||||
p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len;
|
p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len;
|
||||||
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
|
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
|
||||||
UART_EXIT_CRITICAL();
|
UART_EXIT_CRITICAL();
|
||||||
|
// SWO modify
|
||||||
|
if (uart_num == 0 && kSWO_read_num && p_uart_obj[0]->rx_buffered_len >= kSWO_read_num)
|
||||||
|
{
|
||||||
|
if (kSWO_uart_notify_enable)
|
||||||
|
{
|
||||||
|
kSWO_uart_notify_enable = 0;
|
||||||
|
xEventGroupSetBitsFromISR(kSwoThreadEventGroup, UART_GOT_DATA, pdFALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1058,7 +1100,7 @@ esp_err_t my_uart_flush_input(uart_port_t uart_num)
|
||||||
p_uart->rx_ptr = NULL;
|
p_uart->rx_ptr = NULL;
|
||||||
p_uart->rx_cur_remain = 0;
|
p_uart->rx_cur_remain = 0;
|
||||||
p_uart->rx_head_ptr = NULL;
|
p_uart->rx_head_ptr = NULL;
|
||||||
uart_reset_rx_fifo(uart_num);
|
uart_reset_rx_fifo(uart_num); // reset hardware FIFO
|
||||||
my_uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
|
my_uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
|
||||||
xSemaphoreGive(p_uart->rx_mux);
|
xSemaphoreGive(p_uart->rx_mux);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
@ -1096,6 +1138,14 @@ esp_err_t my_uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int t
|
||||||
p_uart_obj[uart_num]->rx_buffered_len = 0;
|
p_uart_obj[uart_num]->rx_buffered_len = 0;
|
||||||
p_uart_obj[uart_num]->wait_tx_done_flg = false;
|
p_uart_obj[uart_num]->wait_tx_done_flg = false;
|
||||||
|
|
||||||
|
// SWO modify
|
||||||
|
if (uart_num == 0)
|
||||||
|
{
|
||||||
|
kSWO_read_index = 0;
|
||||||
|
kSWO_read_num = 0;
|
||||||
|
kSWO_read_mux = xSemaphoreCreateMutex();
|
||||||
|
}
|
||||||
|
|
||||||
if (uart_queue)
|
if (uart_queue)
|
||||||
{
|
{
|
||||||
p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t));
|
p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t));
|
||||||
|
@ -1176,6 +1226,12 @@ esp_err_t my_uart_driver_delete(uart_port_t uart_num)
|
||||||
my_uart_disable_tx_intr(uart_num);
|
my_uart_disable_tx_intr(uart_num);
|
||||||
_xt_isr_mask(0x1 << ETS_UART_INUM);
|
_xt_isr_mask(0x1 << ETS_UART_INUM);
|
||||||
|
|
||||||
|
// SWO modify
|
||||||
|
if (uart_num == 0 && kSWO_read_mux)
|
||||||
|
{
|
||||||
|
vSemaphoreDelete(kSWO_read_mux);
|
||||||
|
}
|
||||||
|
|
||||||
if (p_uart_obj[uart_num]->tx_fifo_sem)
|
if (p_uart_obj[uart_num]->tx_fifo_sem)
|
||||||
{
|
{
|
||||||
vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem);
|
vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem);
|
||||||
|
@ -1254,3 +1310,27 @@ esp_err_t my_uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh
|
||||||
UART_EXIT_CRITICAL();
|
UART_EXIT_CRITICAL();
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SWO modify
|
||||||
|
esp_err_t my_uart_read_bytes_async_swo(uint32_t index, uint32_t length)
|
||||||
|
{
|
||||||
|
if (kSWO_read_num > 0) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
xSemaphoreTake(kSWO_read_mux, (portTickType)portMAX_DELAY);
|
||||||
|
kSWO_read_num = length;
|
||||||
|
kSWO_read_index = index;
|
||||||
|
kSWO_uart_notify_enable = 1;
|
||||||
|
xSemaphoreGive(kSWO_read_mux);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int my_uart_get_rx_buffered_data_len(uart_port_t uart_num)
|
||||||
|
{
|
||||||
|
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
|
||||||
|
UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_ERR_INVALID_ARG);
|
||||||
|
|
||||||
|
return p_uart_obj[uart_num]->rx_buffered_len;
|
||||||
|
}
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
/**
|
/**
|
||||||
* @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.4
|
||||||
* @date 2020-02-04 first version
|
* @change: 2020.02.04 first version
|
||||||
* 2020-11-11 support WinUSB mode
|
* 2020.11.11 support WinUSB mode
|
||||||
*
|
* 2021.02.17 support SWO
|
||||||
* @copyright Copyright (c) 2020
|
*
|
||||||
*
|
* @copyright Copyright (c) 2021
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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 "swo.h"
|
||||||
#include "dap_configuration.h"
|
#include "dap_configuration.h"
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
|
@ -55,10 +58,12 @@ static int dap_respond = 0;
|
||||||
|
|
||||||
|
|
||||||
// SWO Trace
|
// SWO Trace
|
||||||
static int swo_trace_respond = 0;
|
static uint8_t *swo_data_to_send = NULL;
|
||||||
static uint8_t *swo_data_to_send;
|
static uint32_t swo_data_num;
|
||||||
static uint32_t num_swo_data;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// DAP handle
|
||||||
static RingbufHandle_t dap_dataIN_handle = NULL;
|
static RingbufHandle_t dap_dataIN_handle = NULL;
|
||||||
static RingbufHandle_t dap_dataOUT_handle = NULL;
|
static RingbufHandle_t dap_dataOUT_handle = NULL;
|
||||||
static SemaphoreHandle_t data_response_mux = NULL;
|
static SemaphoreHandle_t data_response_mux = NULL;
|
||||||
|
@ -76,7 +81,7 @@ void handle_dap_data_request(usbip_stage2_header *header, uint32_t length)
|
||||||
|
|
||||||
// always send constant size buf -> cuz we don't care about the IN packet size
|
// 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
|
// 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);
|
xRingbufferSend(dap_dataIN_handle, data_in - sizeof(uint32_t), DAP_HANDLE_SIZE, portMAX_DELAY);
|
||||||
xTaskNotifyGive(kDAPTaskHandle);
|
xTaskNotifyGive(kDAPTaskHandle);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -110,17 +115,17 @@ void handle_dap_data_response(usbip_stage2_header *header)
|
||||||
|
|
||||||
void handle_swo_trace_response(usbip_stage2_header *header)
|
void handle_swo_trace_response(usbip_stage2_header *header)
|
||||||
{
|
{
|
||||||
// TODO:
|
|
||||||
send_stage2_submit(header, 0, 0);
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (swo_trace_respond)
|
if (kSwoTransferBusy)
|
||||||
{
|
{
|
||||||
swo_trace_respond = 0;
|
// busy indicates that there is data to be send
|
||||||
//send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, DAP_PACKET_SIZE);
|
printf("swo use data\r\n");
|
||||||
|
send_stage2_submit_data(header, 0, (void *)swo_data_to_send, swo_data_num);
|
||||||
|
SWO_TransferComplete();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// nothing to send.
|
||||||
send_stage2_submit(header, 0, 0);
|
send_stage2_submit(header, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,15 +136,7 @@ void handle_swo_trace_response(usbip_stage2_header *header)
|
||||||
void SWO_QueueTransfer(uint8_t *buf, uint32_t num)
|
void SWO_QueueTransfer(uint8_t *buf, uint32_t num)
|
||||||
{
|
{
|
||||||
swo_data_to_send = buf;
|
swo_data_to_send = buf;
|
||||||
num_swo_data = num;
|
swo_data_num = 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)
|
void DAP_Thread(void *argument)
|
||||||
|
@ -181,7 +178,7 @@ void DAP_Thread(void *argument)
|
||||||
ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
|
ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
|
||||||
packetSize = 0;
|
packetSize = 0;
|
||||||
item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize,
|
item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize,
|
||||||
(1 / portTICK_RATE_MS), DAP_HANDLE_SIZE);
|
pdMS_TO_TICKS(1), DAP_HANDLE_SIZE);
|
||||||
if (packetSize == 0)
|
if (packetSize == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -200,7 +197,7 @@ void DAP_Thread(void *argument)
|
||||||
item->buf[0] = ID_DAP_ExecuteCommands;
|
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 = 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
|
resLength &= 0xFFFF; // res length in lower 16 bits
|
||||||
|
|
||||||
vRingbufferReturnItem(dap_dataIN_handle, (void *)item); // process done.
|
vRingbufferReturnItem(dap_dataIN_handle, (void *)item); // process done.
|
||||||
|
@ -229,7 +226,7 @@ int fast_reply(uint8_t *buf, uint32_t length)
|
||||||
DAPPacetDataType *item;
|
DAPPacetDataType *item;
|
||||||
size_t packetSize = 0;
|
size_t packetSize = 0;
|
||||||
item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize,
|
item = (DAPPacetDataType *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize,
|
||||||
(10 / portTICK_RATE_MS), DAP_HANDLE_SIZE);
|
pdMS_TO_TICKS(10), DAP_HANDLE_SIZE);
|
||||||
if (packetSize == DAP_HANDLE_SIZE)
|
if (packetSize == DAP_HANDLE_SIZE)
|
||||||
{
|
{
|
||||||
unpack((uint32_t *)buf, sizeof(usbip_stage2_header));
|
unpack((uint32_t *)buf, sizeof(usbip_stage2_header));
|
||||||
|
@ -240,7 +237,7 @@ int fast_reply(uint8_t *buf, uint32_t length)
|
||||||
#else
|
#else
|
||||||
send_stage2_submit_data((usbip_stage2_header *)buf, 0, item->buf, DAP_HANDLE_SIZE);
|
send_stage2_submit_data((usbip_stage2_header *)buf, 0, item->buf, DAP_HANDLE_SIZE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
|
if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
|
||||||
{
|
{
|
||||||
|
@ -259,7 +256,7 @@ int fast_reply(uint8_t *buf, uint32_t length)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//// TODO: ep0 dir 0 ?
|
//// TODO: ep0 dir 0 ?
|
||||||
buf[0x3] = 0x3; // command
|
buf[0x3] = 0x3; // command
|
||||||
buf[0xF] = 0; // direction
|
buf[0xF] = 0; // direction
|
||||||
buf[0x16] = 0;
|
buf[0x16] = 0;
|
||||||
|
|
37
main/main.c
37
main/main.c
|
@ -26,16 +26,19 @@
|
||||||
#include "tcp_server.h"
|
#include "tcp_server.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "wifi_configuration.h"
|
#include "wifi_configuration.h"
|
||||||
|
#include "DAP_config.h"
|
||||||
|
|
||||||
|
|
||||||
extern void SWO_Thread(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);
|
||||||
|
extern void SWO_Thread();
|
||||||
|
|
||||||
|
TaskHandle_t kDAPTaskHandle = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
const int IPV4_GOTIP_BIT = BIT0;
|
const int IPV4_GOTIP_BIT = BIT0;
|
||||||
#ifdef CONFIG_EXAMPLE_IPV6
|
#ifdef CONFIG_EXAMPLE_IPV6
|
||||||
|
@ -128,15 +131,35 @@ static void wait_for_ip()
|
||||||
|
|
||||||
void app_main()
|
void app_main()
|
||||||
{
|
{
|
||||||
|
// struct rst_info *rtc_info = system_get_rst_info();
|
||||||
|
|
||||||
|
// os_printf("reset reason: %x\n", rtc_info->reason);
|
||||||
|
|
||||||
|
// if (rtc_info->reason == REASON_WDT_RST ||
|
||||||
|
// rtc_info->reason == REASON_EXCEPTION_RST ||
|
||||||
|
// rtc_info->reason == REASON_SOFT_WDT_RST)
|
||||||
|
// {
|
||||||
|
// if (rtc_info->reason == REASON_EXCEPTION_RST)
|
||||||
|
// {
|
||||||
|
// os_printf("Fatal exception (%d):\n", rtc_info->exccause);
|
||||||
|
// }
|
||||||
|
// os_printf("epc1=0x%08x, epc2=0x%08x, epc3=0x%08x,excvaddr=0x%08x, depc=0x%08x\n",
|
||||||
|
// rtc_info->epc1, rtc_info->epc2, rtc_info->epc3,
|
||||||
|
// rtc_info->excvaddr, rtc_info->depc);
|
||||||
|
// }
|
||||||
|
|
||||||
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();
|
||||||
|
timer_init();
|
||||||
|
|
||||||
|
|
||||||
xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL);
|
|
||||||
xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 14, NULL);
|
xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 14, NULL);
|
||||||
xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 10, &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);
|
#if (SWO_FUNCTION_ENABLE == 1)
|
||||||
//xTaskCreate(usart_monitor_task, "uart_task", 512, NULL, 6, NULL);
|
xTaskCreate(SWO_Thread, "SWO_Task", 512, NULL, 10, NULL);
|
||||||
|
#endif
|
||||||
|
// It seems that the task is overly stressful...
|
||||||
}
|
}
|
||||||
|
|
47
main/timer.c
47
main/timer.c
|
@ -1,29 +1,52 @@
|
||||||
/**
|
/**
|
||||||
* @file timer.c
|
* @file timer.c
|
||||||
* @brief Hardware timer for DAP timestamp
|
* @brief Hardware timer for DAP timestamp
|
||||||
* @version 0.1
|
* @change: 2021-02-18 Using the FRC2 timer
|
||||||
|
*
|
||||||
|
* @version 0.2
|
||||||
* @date 2020-01-22
|
* @date 2020-01-22
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2020
|
* @copyright Copyright (c) 2021
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "hw_timer.h"
|
#include "hw_timer.h"
|
||||||
#include "timer_struct.h"
|
#include "timer_struct.h"
|
||||||
|
|
||||||
|
#include "cmsis_compiler.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"
|
||||||
void timer_create_task()
|
|
||||||
|
/*
|
||||||
|
Note:
|
||||||
|
System bus frequency is 80MHz, will not be affected by CPU frequency. The
|
||||||
|
frequency of UART, SPI, or other peripheral devices, are divided from system
|
||||||
|
bus frequency, so they will not be affected by CPU frequency either.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TIMER_BASE 0x60000600
|
||||||
|
volatile frc2_struct_t * frc2 = (frc2_struct_t *)(TIMER_BASE + (1) * 0x20);
|
||||||
|
|
||||||
|
void timer_init()
|
||||||
{
|
{
|
||||||
// FRC1 frequency 80MHz
|
|
||||||
vPortEnterCritical();
|
vPortEnterCritical();
|
||||||
frc1.ctrl.div = TIMER_CLKDIV_16; // 80MHz / 16 = 5MHz
|
frc2->ctrl.div = TIMER_CLKDIV_16; // 80MHz / 16 = 5MHz
|
||||||
frc1.ctrl.intr_type = TIMER_EDGE_INT;
|
frc2->ctrl.intr_type = TIMER_EDGE_INT;
|
||||||
frc1.ctrl.reload = 0x01;
|
frc2->ctrl.reload = 0x01; // enable auto reload
|
||||||
frc1.load.data = 0x7FFFFF; // 23bit??
|
frc2->load.val = 0x7FFFFFFF; // 31bit max
|
||||||
frc1.ctrl.en = 0x01;
|
frc2->ctrl.en = 0x01;
|
||||||
vPortExitCritical();
|
vPortExitCritical();
|
||||||
vTaskDelete(NULL);
|
}
|
||||||
|
|
||||||
|
// Timing up to 2147483647(0x7FFFFFFF) / 5000000(5MHz) = 429s
|
||||||
|
// 0.2 micro-second resolution
|
||||||
|
uint32_t get_timer_count()
|
||||||
|
{
|
||||||
|
return (uint32_t)frc2->count.data;
|
||||||
}
|
}
|
69
main/timer.h
69
main/timer.h
|
@ -1,6 +1,71 @@
|
||||||
|
/**
|
||||||
|
* @file timer.h
|
||||||
|
* @author windowsair
|
||||||
|
* @brief esp8266 hardware timer
|
||||||
|
* @change: 2021-02-18 Add frc2 timer
|
||||||
|
* @note
|
||||||
|
* FRC2 is not officially documented. There is no guarantee of its behavior.
|
||||||
|
* FRC2 may be used for RTC functions. May be reserved for other functions in the future.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2021-02-18
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
#ifndef __TIMER_H__
|
#ifndef __TIMER_H__
|
||||||
#define __TIMER_H__
|
#define __TIMER_H__
|
||||||
|
|
||||||
void timer_create_task();
|
#include <stdint.h>
|
||||||
|
|
||||||
#endif
|
|
||||||
|
// FRC2 is a 32-bit countup timer
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t data: 32;
|
||||||
|
};
|
||||||
|
uint32_t val;
|
||||||
|
} load;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t data: 31;
|
||||||
|
uint32_t reserved23: 1;
|
||||||
|
};
|
||||||
|
uint32_t val;
|
||||||
|
} count;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t div: 6;
|
||||||
|
uint32_t reload: 1;
|
||||||
|
uint32_t en: 1;
|
||||||
|
uint32_t intr_type: 1;
|
||||||
|
uint32_t reserved24: 23;
|
||||||
|
};
|
||||||
|
uint32_t val;
|
||||||
|
} ctrl;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t clr: 1;
|
||||||
|
uint32_t reserved1: 31;
|
||||||
|
};
|
||||||
|
uint32_t val;
|
||||||
|
} intr;
|
||||||
|
} frc2_struct_t;
|
||||||
|
|
||||||
|
extern volatile frc2_struct_t* frc2;
|
||||||
|
|
||||||
|
extern void timer_init();
|
||||||
|
extern uint32_t get_timer_count();
|
||||||
|
|
||||||
|
#endif
|
|
@ -104,10 +104,12 @@ CONFIG_USING_NEW_ETS_VPRINTF=y
|
||||||
# CONFIG_LINK_ETS_PRINTF_TO_IRAM is not set
|
# CONFIG_LINK_ETS_PRINTF_TO_IRAM is not set
|
||||||
CONFIG_SOC_FULL_ICACHE=y
|
CONFIG_SOC_FULL_ICACHE=y
|
||||||
CONFIG_SOC_IRAM_SIZE=0x8000
|
CONFIG_SOC_IRAM_SIZE=0x8000
|
||||||
CONFIG_CONSOLE_UART_DEFAULT=y
|
# CONFIG_CONSOLE_UART_DEFAULT is not set
|
||||||
# CONFIG_CONSOLE_UART_CUSTOM is not set
|
CONFIG_CONSOLE_UART_CUSTOM=y
|
||||||
# CONFIG_CONSOLE_UART_NONE is not set
|
# CONFIG_CONSOLE_UART_NONE is not set
|
||||||
CONFIG_CONSOLE_UART_NUM=0
|
# CONFIG_CONSOLE_UART_CUSTOM_NUM_0 is not set
|
||||||
|
CONFIG_CONSOLE_UART_CUSTOM_NUM_1=y
|
||||||
|
CONFIG_CONSOLE_UART_NUM=1
|
||||||
CONFIG_CONSOLE_UART_BAUDRATE=74880
|
CONFIG_CONSOLE_UART_BAUDRATE=74880
|
||||||
# CONFIG_UART0_SWAP_IO is not set
|
# CONFIG_UART0_SWAP_IO is not set
|
||||||
# CONFIG_DISABLE_ROM_UART_PRINT is not set
|
# CONFIG_DISABLE_ROM_UART_PRINT is not set
|
||||||
|
|
Loading…
Reference in New Issue