0
0
Fork 0

feat: DAP function completion

1. Add streaming SWO trace support(Not tested)
2. Fix Unlink function
This commit is contained in:
windowsair 2020-01-28 20:21:18 +08:00
parent 50079136ab
commit 1070f63074
9 changed files with 2398 additions and 353 deletions

View File

@ -1,5 +1,5 @@
set(COMPONENT_ADD_INCLUDEDIRS "config include $ENV{IDF_PATH}/components/esp8266/include/esp8266/") 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 ") 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/SWO.c
register_component() register_component()

View File

@ -113,7 +113,7 @@ This information includes:
#define SWO_UART 1 ///< SWO UART: 1 = available, 0 = not available. #define SWO_UART 1 ///< SWO UART: 1 = available, 0 = not available.
/// Maximum SWO UART Baudrate. /// Maximum SWO UART Baudrate.
#define SWO_UART_MAX_BAUDRATE 50000000U ///< SWO UART Maximum Baudrate in Hz. #define SWO_UART_MAX_BAUDRATE (115200U*40U) ///< SWO UART Maximum Baudrate in Hz.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz
//// TODO: uncertain value //// TODO: uncertain value

View File

@ -0,0 +1,565 @@
/**
* @brief Made some simple modifications to the official UART
*
*/
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _DRIVER_UART_H_
#define _DRIVER_UART_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/queue.h"
#define UART_FIFO_LEN (128) /*!< Length of the hardware FIFO buffers */
#define UART_INTR_MASK 0x1ff /*!< Mask of all UART interrupts */
#define UART_LINE_INV_MASK (0x3f << 19) /*!< TBD */
#define UART_INVERSE_DISABLE (0x0) /*!< Disable UART signal inverse*/
#define UART_INVERSE_RXD (BIT(19)) /*!< UART RXD input inverse*/
#define UART_INVERSE_CTS (BIT(20)) /*!< UART CTS input inverse*/
#define UART_INVERSE_TXD (BIT(22)) /*!< UART TXD output inverse*/
#define UART_INVERSE_RTS (BIT(23)) /*!< UART RTS output inverse*/
/**
* @brief UART mode selection
*/
typedef enum {
UART_MODE_UART = 0x00, /*!< mode: regular UART mode*/
} uart_mode_t;
/**
* @brief UART word length constants
*/
typedef enum {
UART_DATA_5_BITS = 0x0, /*!< word length: 5bits*/
UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/
UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/
UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/
UART_DATA_BITS_MAX = 0x4,
} uart_word_length_t;
/**
* @brief UART stop bits number
*/
typedef enum {
UART_STOP_BITS_1 = 0x1, /*!< stop bit: 1bit*/
UART_STOP_BITS_1_5 = 0x2, /*!< stop bit: 1.5bits*/
UART_STOP_BITS_2 = 0x3, /*!< stop bit: 2bits*/
UART_STOP_BITS_MAX = 0x4,
} uart_stop_bits_t;
/**
* @brief UART peripheral number
*/
typedef enum {
UART_NUM_0 = 0x0,
UART_NUM_1 = 0x1,
UART_NUM_MAX,
} uart_port_t;
/**
* @brief UART parity constants
*/
typedef enum {
UART_PARITY_DISABLE = 0x0, /*!< Disable UART parity*/
UART_PARITY_EVEN = 0x2, /*!< Enable UART even parity*/
UART_PARITY_ODD = 0x3 /*!< Enable UART odd parity*/
} uart_parity_t;
/**
* @brief UART hardware flow control modes
*/
typedef enum {
UART_HW_FLOWCTRL_DISABLE = 0x0, /*!< disable hardware flow control*/
UART_HW_FLOWCTRL_RTS = 0x1, /*!< enable RX hardware flow control (rts)*/
UART_HW_FLOWCTRL_CTS = 0x2, /*!< enable TX hardware flow control (cts)*/
UART_HW_FLOWCTRL_CTS_RTS = 0x3, /*!< enable hardware flow control*/
UART_HW_FLOWCTRL_MAX = 0x4,
} uart_hw_flowcontrol_t;
/**
* @brief UART configuration parameters for my_uart_param_config function
*/
typedef struct {
int baud_rate; /*!< UART baud rate*/
uart_word_length_t data_bits; /*!< UART byte size*/
uart_parity_t parity; /*!< UART parity mode*/
uart_stop_bits_t stop_bits; /*!< UART stop bits*/
uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode (cts/rts)*/
uint8_t rx_flow_ctrl_thresh; /*!< UART HW RTS threshold*/
} uart_config_t;
/**
* @brief UART interrupt configuration parameters for my_uart_intr_config function
*/
typedef struct {
uint32_t intr_enable_mask; /*!< UART interrupt enable mask, choose from UART_XXXX_INT_ENA_M under UART_INT_ENA_REG(i), connect with bit-or operator*/
uint8_t rx_timeout_thresh; /*!< UART timeout interrupt threshold (unit: time of sending one byte)*/
uint8_t txfifo_empty_intr_thresh; /*!< UART TX empty interrupt threshold.*/
uint8_t rxfifo_full_thresh; /*!< UART RX full interrupt threshold.*/
} uart_intr_config_t;
/**
* @brief UART event types used in the ring buffer
*/
typedef enum {
UART_DATA, /*!< UART data event*/
UART_BUFFER_FULL, /*!< UART RX buffer full event*/
UART_FIFO_OVF, /*!< UART FIFO overflow event*/
UART_FRAME_ERR, /*!< UART RX frame error event*/
UART_PARITY_ERR, /*!< UART RX parity event*/
UART_EVENT_MAX, /*!< UART event max index*/
} uart_event_type_t;
/**
* @brief Event structure used in UART event queue
*/
typedef struct {
uart_event_type_t type; /*!< UART event type */
size_t size; /*!< UART data size for UART_DATA event*/
} uart_event_t;
/**
* @brief Set UART data bits.
*
* @param uart_num Uart port number.
* @param data_bit Uart data bits.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit);
/**
* @brief Get UART data bits.
*
* @param uart_num Uart port number.
* @param data_bit Pointer to accept value of UART data bits.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_word_length(uart_port_t uart_num, uart_word_length_t *data_bit);
/**
* @brief Set UART stop bits.
*
* @param uart_num Uart port number
* @param stop_bits Uart stop bits
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bits);
/**
* @brief Get UART stop bits.
*
* @param uart_num Uart port number.
* @param stop_bits Pointer to accept value of UART stop bits.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t *stop_bits);
/**
* @brief Set UART parity mode.
*
* @param uart_num Uart port number.
* @param parity_mode The enum of uart parity configuration.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode);
/**
* @brief Get UART parity mode.
*
* @param uart_num Uart port number
* @param parity_mode Pointer to accept value of UART parity mode.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_parity(uart_port_t uart_num, uart_parity_t *parity_mode);
/**
* @brief Set UART baud rate.
*
* @param uart_num Uart port number
* @param baudrate UART baud rate.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate);
/**
* @brief Get UART baud rate.
*
* @param uart_num Uart port number.
* @param baudrate Pointer to accept value of Uart baud rate.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate);
/**
* @brief Set UART line inverse mode
*
* @param uart_num UART_NUM_0
* @param inverse_mask Choose the wires that need to be inverted.
* Inverse_mask should be chosen from
* UART_INVERSE_RXD / UART_INVERSE_TXD / UART_INVERSE_RTS / UART_INVERSE_CTS,
* combined with OR operation.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask);
/**
* @brief Configure Hardware flow control.
*
* @param uart_num Uart port number.
* @param flow_ctrl Hardware flow control mode.
* @param rx_thresh Threshold of Hardware flow control.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh);
/**
* @brief Get hardware flow control mode
*
* @param uart_num Uart port number.
* @param flow_ctrl Option for different flow control mode.
*
* @return
* - ESP_OK Success, result will be put in (*flow_ctrl)
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t *flow_ctrl);
/**
* @brief UART0 swap.
* Use MTCK as UART0 RX, MTDO as UART0 TX, so ROM log will not output from
* this new UART0. We also need to use MTDO (U0RTS) and MTCK (U0CTS) as UART0 in hardware.
*
* @return
* - ESP_OK Success
*/
esp_err_t my_uart_enable_swap(void);
/**
* @brief Disable UART0 swap.
* Use the original UART0, not MTCK and MTDO.
*
* @return
* - ESP_OK Success
*/
esp_err_t my_uart_disable_swap(void);
/**
* @brief Clear uart interrupts status.
*
* @param uart_num Uart port number.
* @param mask Uart interrupt bits mask.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_clear_intr_status(uart_port_t uart_num, uint32_t mask);
/**
* @brief Set UART interrupt enable
*
* @param uart_num Uart port number
* @param enable_mask Bit mask of the enable bits.
* The bit mask should be composed from the fields of register UART_INT_ENA_REG.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask);
/**
* @brief Clear UART interrupt enable bits
*
* @param uart_num Uart port number
* @param disable_mask Bit mask of the disable bits.
* The bit mask should be composed from the fields of register UART_INT_ENA_REG.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask);
/**
* @brief Enable UART RX interrupt (RX_FULL & RX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_enable_rx_intr(uart_port_t uart_num);
/**
* @brief Disable UART RX interrupt (RX_FULL & RX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_disable_rx_intr(uart_port_t uart_num);
/**
* @brief Disable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_disable_tx_intr(uart_port_t uart_num);
/**
* @brief Enable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT)
*
* @param uart_num UART_NUM_0
* @param enable 1: enable; 0: disable
* @param thresh Threshold of TX interrupt, 0 ~ UART_FIFO_LEN
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh);
/**
* @brief Register UART interrupt handler (ISR).
*
* @param uart_num UART_NUM_0
* @param fn Interrupt handler function.
* @param arg parameter for handler function
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_isr_register(uart_port_t uart_num, void (*fn)(void *), void *arg);
/**
* @brief Config Common parameters of serial ports.
*
* @param uart_num Uart port number.
* @param uart_conf Uart config parameters.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_param_config(uart_port_t uart_num, uart_config_t *uart_conf);
/**
* @brief Config types of uarts.
*
* @param uart_num Uart port number.
* @param uart_intr_conf Uart interrupt config parameters.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_intr_config(uart_port_t uart_num, uart_intr_config_t *uart_intr_conf);
/**
* @brief Install UART driver.
*
* @note Rx_buffer_size should be greater than UART_FIFO_LEN. Tx_buffer_size should be either zero or greater than UART_FIFO_LEN.
*
* @param uart_num Uart port number.
* @param rx_buffer_size UART RX ring buffer size.
* @param tx_buffer_size UART TX ring buffer size.
* If set to zero, driver will not use TX buffer, TX function will block task until all data have been sent out.
* @param queue_size UART event queue size/depth.
* @param uart_queue UART event queue handle (out param). On success, a new queue handle is written here to provide
* access to UART events. If set to NULL, driver will not use an event queue.
* @param no_use Invalid parameters, just to fit some modules.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, QueueHandle_t *uart_queue, int no_use);
/**
* @brief Uninstall UART driver.
*
* @param uart_num Uart port number.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_driver_delete(uart_port_t uart_num);
/**
* @brief Waiting for the last byte of data to be sent
*
* @param uart_num Uart port number.
* @param ticks_to_wait Timeout, count in RTOS ticks
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait);
/**
* @brief Send data to the UART port from a given buffer and length.
*
* This function will not wait for enough space in TX FIFO. It will just fill the available TX FIFO and return when the FIFO is full.
* @note This function should only be used when UART TX buffer is not enabled.
*
* @param uart_num Uart port number.
* @param buffer data buffer address
* @param len data length to send
*
* @return
* - (-1) Parameter error
* - OTHERS (>=0) The number of bytes pushed to the TX FIFO
*/
int my_uart_tx_chars(uart_port_t uart_num, const char *buffer, uint32_t len);
/**
* @brief Send data to the UART port from a given buffer and length,
*
* If the UART driver's parameter 'tx_buffer_size' is set to zero:
* This function will not return until all the data have been sent out, or at least pushed into TX FIFO.
*
* Otherwise, if the 'tx_buffer_size' > 0, this function will return after copying all the data to tx ring buffer,
* UART ISR will then move data from the ring buffer to TX FIFO gradually.
*
* @param uart_num Uart port number.
* @param src data buffer address
* @param size data length to send
*
* @return
* - (-1) Parameter error
* - OTHERS (>=0) The number of bytes pushed to the TX FIFO
*/
int my_uart_write_bytes(uart_port_t uart_num, const char *src, size_t size);
/**
* @brief UART read bytes from UART buffer
*
* @param uart_num Uart port number.
* @param buf pointer to the buffer.
* @param length data length
* @param ticks_to_wait sTimeout, count in RTOS ticks
*
* @return
* - (-1) Error
* - OTHERS (>=0) The number of bytes read from UART FIFO
*/
int my_uart_read_bytes(uart_port_t uart_num, uint8_t *buf, uint32_t length, TickType_t ticks_to_wait);
/**
* @brief Alias of my_uart_flush_input.
* UART ring buffer flush. This will discard all data in the UART RX buffer.
* @note Instead of waiting the data sent out, this function will clear UART rx buffer.
* In order to send all the data in tx FIFO, we can use my_uart_wait_tx_done function.
* @param uart_num UART port number.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_flush(uart_port_t uart_num);
/**
* @brief Clear input buffer, discard all the data is in the ring-buffer.
* @note In order to send all the data in tx FIFO, we can use my_uart_wait_tx_done function.
* @param uart_num UART port number.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_flush_input(uart_port_t uart_num);
/**
* @brief UART get RX ring buffer cached data length
*
* @param uart_num UART port number.
* @param size Pointer of size_t to accept cached data length
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_get_buffered_data_len(uart_port_t uart_num, size_t *size);
/**
* @brief UART set threshold timeout for TOUT feature
*
* @param uart_num Uart number to configure
* @param tout_thresh This parameter defines timeout threshold in uart symbol periods. The maximum value of threshold is 126.
* tout_thresh = 1, defines TOUT interrupt timeout equal to transmission time of one symbol (~11 bit) on current baudrate.
* If the time is expired the UART_RXFIFO_TOUT_INT interrupt is triggered. If tout_thresh == 0,
* the TOUT feature is disabled.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t my_uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh);
#ifdef __cplusplus
}
#endif
#endif // _DRIVER_UART_H_

View File

@ -1,3 +1,8 @@
/**
* @brief Modify this file to fit esp8266 Uart
*
*/
/* /*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved. * Copyright (c) 2013-2017 ARM Limited. All rights reserved.
* *
@ -27,14 +32,21 @@
#include "DAP_config.h" #include "DAP_config.h"
#include "DAP.h" #include "DAP.h"
/*
#if (SWO_UART != 0) #include "esp_err.h"
#include "Driver_USART.h" #include "freertos/FreeRTOS.h"
#endif #include "freertos/task.h"
#if (SWO_STREAM != 0) #include "freertos/event_groups.h"
#include "cmsis_os2.h" #include "uart_modify.h"
#endif
*/
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)
#ifdef DAP_FW_V1 #ifdef DAP_FW_V1
@ -45,24 +57,18 @@
#if (SWO_UART != 0) #if (SWO_UART != 0)
#ifndef USART_PORT #ifndef USART_PORT
#define USART_PORT 0 /* USART Port Number */ #define USART_PORT UART_NUM_0 /* USART Port Number */
#endif #endif
// USART Driver
#define _USART_Driver_(n) Driver_USART##n
#define USART_Driver_(n) _USART_Driver_(n)
extern ARM_DRIVER_USART USART_Driver_(USART_PORT);
#define pUSART (&USART_Driver_(USART_PORT))
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 50U /* 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) */
@ -83,7 +89,8 @@ static uint32_t TraceBlockSize; /* Current Trace Block Size */
#if (TIMESTAMP_CLOCK != 0U) #if (TIMESTAMP_CLOCK != 0U)
// Trace Timestamp // Trace Timestamp
static volatile struct { static volatile struct
{
uint32_t index; uint32_t index;
uint32_t tick; uint32_t tick;
} TraceTimestamp; } TraceTimestamp;
@ -94,26 +101,32 @@ 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);
static void SetTraceError (uint8_t flag); void SetTraceError(uint8_t flag);
#if (SWO_STREAM != 0) #if (SWO_STREAM != 0)
extern osThreadId_t SWO_ThreadId;
static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */ static volatile uint8_t TransferBusy = 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)
// USART Driver Callback function
// event: event mask void usart_monitor_task(void *argument)
static void USART_Callback (uint32_t event) { {
uint32_t index_i; uint32_t index_i;
uint32_t index_o; uint32_t index_o;
uint32_t count; uint32_t count;
uint32_t num; uint32_t num;
uint32_t flags;
if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) { 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) #if (TIMESTAMP_CLOCK != 0U)
TraceTimestamp.tick = TIMESTAMP_GET(); TraceTimestamp.tick = TIMESTAMP_GET();
#endif #endif
@ -124,102 +137,140 @@ static void USART_Callback (uint32_t event) {
#if (TIMESTAMP_CLOCK != 0U) #if (TIMESTAMP_CLOCK != 0U)
TraceTimestamp.index = index_i; TraceTimestamp.index = index_i;
#endif #endif
num = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U)); 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; count = index_i - index_o;
if (count <= (SWO_BUFFER_SIZE - num)) { // 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; index_i &= SWO_BUFFER_SIZE - 1U;
TraceBlockSize = num; TraceBlockSize = num;
pUSART->Receive(&TraceBuf[index_i], num); my_uart_read_bytes(USART_PORT, &TraceBuf[index_i], num, 20 / portTICK_RATE_MS);
} else { //pUSART->Receive(&TraceBuf[index_i], num);
}
else
{
// Not enough buffers
TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED; TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED;
} }
TraceUpdate = 1U; TraceUpdate = 1U;
#if (SWO_STREAM != 0) #if (SWO_STREAM != 0)
if (TraceTransport == 2U) { if (TraceTransport == 2U)
if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U)))) { {
osThreadFlagsSet(SWO_ThreadId, 1U); if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U))))
{
xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
} }
} }
#endif #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);
} }
// 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) { __WEAK 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 = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
my_uart_param_config(USART_PORT, &uart_config);
if (enable != 0U) { #define BUF_SIZE (1024)
status = pUSART->Initialize(USART_Callback); my_uart_driver_install(USART_PORT, BUF_SIZE, 0, 0, NULL, 0);
if (status != ARM_DRIVER_OK) {
if (enable != 0U)
{
my_uart_param_config(USART_PORT, &uart_config);
status = my_uart_driver_install(USART_PORT, BUF_SIZE, 0, 0, NULL, 0);
if (status != ESP_OK)
{
return (0U); return (0U);
} }
status = pUSART->PowerControl(ARM_POWER_FULL);
if (status != ARM_DRIVER_OK) {
pUSART->Uninitialize();
return (0U);
} }
} else { else
pUSART->Control(ARM_USART_CONTROL_RX, 0U); {
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); my_uart_driver_delete(USART_PORT);
pUSART->PowerControl(ARM_POWER_OFF);
pUSART->Uninitialize();
} }
return (1U); return (1U);
} }
// 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) { __WEAK uint32_t UART_SWO_Baudrate(uint32_t baudrate)
{
int32_t status; int32_t status;
uint32_t index; uint32_t index;
uint32_t num; uint32_t num;
if (baudrate > SWO_UART_MAX_BAUDRATE) { if (baudrate > SWO_UART_MAX_BAUDRATE)
{
baudrate = SWO_UART_MAX_BAUDRATE; baudrate = SWO_UART_MAX_BAUDRATE;
} }
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
pUSART->Control(ARM_USART_CONTROL_RX, 0U); {
if (pUSART->GetStatus().rx_busy) { size_t len = 0;
TraceIndexI += pUSART->GetRxCount(); my_uart_get_buffered_data_len(USART_PORT, &len);
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); my_uart_flush(USART_PORT);
} TraceIndexI += len;
// pUSART->Control(ARM_USART_CONTROL_RX, 0U);
// if (pUSART->GetStatus().rx_busy)
// {
// TraceIndexI += pUSART->GetRxCount();
// pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
// }
} }
status = pUSART->Control(ARM_USART_MODE_ASYNCHRONOUS | /////////////
ARM_USART_DATA_BITS_8 | status = my_uart_set_baudrate(USART_PORT, baudrate);
ARM_USART_PARITY_NONE |
ARM_USART_STOP_BITS_1,
baudrate);
if (status == ARM_DRIVER_OK) { if (status == ESP_OK)
{
USART_Ready = 1U; USART_Ready = 1U;
} else { }
else
{
USART_Ready = 0U; USART_Ready = 0U;
return (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);
num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U)); num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U));
TraceBlockSize = num; TraceBlockSize = num;
pUSART->Receive(&TraceBuf[index], num); //pUSART->Receive(&TraceBuf[index], num);
my_uart_read_bytes(USART_PORT, &TraceBuf[index], num, 20 / portTICK_RATE_MS);
} }
pUSART->Control(ARM_USART_CONTROL_RX, 1U); //pUSART->Control(ARM_USART_CONTROL_RX, 1U); ////TODO:
} }
return (baudrate); return (baudrate);
@ -228,28 +279,40 @@ __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) { __WEAK uint32_t UART_SWO_Control(uint32_t active)
{
int32_t status; int32_t status;
if (active) { if (active)
if (!USART_Ready) { {
if (!USART_Ready)
{
return (0U); return (0U);
} }
TraceBlockSize = 1U; TraceBlockSize = 1U;
status = pUSART->Receive(&TraceBuf[0], 1U); status = my_uart_read_bytes(USART_PORT, &TraceBuf[0], 1U, 20 / portTICK_RATE_MS);
if (status != ARM_DRIVER_OK) { if (status == ESP_FAIL)
{
return (0U); return (0U);
} }
status = pUSART->Control(ARM_USART_CONTROL_RX, 1U); // status = pUSART->Control(ARM_USART_CONTROL_RX, 1U);
if (status != ARM_DRIVER_OK) { // if (status != ARM_DRIVER_OK)
return (0U); // {
} // return (0U);
} else { // } ////TODO:
pUSART->Control(ARM_USART_CONTROL_RX, 0U);
if (pUSART->GetStatus().rx_busy) {
TraceIndexI += pUSART->GetRxCount();
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
} }
else
{
size_t len = 0;
my_uart_get_buffered_data_len(USART_PORT, &len);
my_uart_flush(USART_PORT);
TraceIndexI += len;
// pUSART->Control(ARM_USART_CONTROL_RX, 0U);
// if (pUSART->GetStatus().rx_busy)
// {
// TraceIndexI += pUSART->GetRxCount();
// pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
// }
} }
return (1U); return (1U);
} }
@ -257,70 +320,83 @@ __WEAK uint32_t UART_SWO_Control (uint32_t active) {
// Start UART SWO Capture // Start UART SWO Capture
// buf: pointer to buffer for capturing // buf: pointer to buffer for capturing
// num: number of bytes to capture // num: number of bytes to capture
__WEAK void UART_SWO_Capture (uint8_t *buf, uint32_t num) { __WEAK void UART_SWO_Capture(uint8_t *buf, uint32_t num)
{
TraceBlockSize = num; TraceBlockSize = num;
pUSART->Receive(buf, num); my_uart_read_bytes(USART_PORT, buf, num, 20 / portTICK_RATE_MS);
} }
// 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) { __WEAK uint32_t UART_SWO_GetCount(void)
{
uint32_t count; uint32_t count;
if (pUSART->GetStatus().rx_busy) { // if (pUSART->GetStatus().rx_busy)
count = pUSART->GetRxCount(); // {
} else { // count = pUSART->GetRxCount();
count = 0U; // }
} // else
// {
// count = 0U;
// }
my_uart_get_buffered_data_len(USART_PORT, &count);
return (count); return (count);
} }
#endif /* (SWO_UART != 0) */ #endif /* (SWO_UART != 0) */
#if (SWO_MANCHESTER != 0) #if (SWO_MANCHESTER != 0)
// Enable or disable Manchester SWO Mode // Enable or disable Manchester SWO Mode
// enable: enable flag // enable: enable flag
// return: 1 - Success, 0 - Error // return: 1 - Success, 0 - Error
__WEAK uint32_t Manchester_SWO_Mode (uint32_t enable) { __WEAK uint32_t Manchester_SWO_Mode(uint32_t enable)
{
return (0U); return (0U);
} }
// Configure Manchester SWO Baudrate // Configure Manchester 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 Manchester_SWO_Baudrate (uint32_t baudrate) { __WEAK uint32_t Manchester_SWO_Baudrate(uint32_t baudrate)
{
return (0U); return (0U);
} }
// Control Manchester SWO Capture // Control Manchester SWO Capture
// active: active flag // active: active flag
// return: 1 - Success, 0 - Error // return: 1 - Success, 0 - Error
__WEAK uint32_t Manchester_SWO_Control (uint32_t active) { __WEAK uint32_t Manchester_SWO_Control(uint32_t active)
{
return (0U); return (0U);
} }
// Start Manchester SWO Capture // Start Manchester SWO Capture
// buf: pointer to buffer for capturing // buf: pointer to buffer for capturing
// num: number of bytes to capture // num: number of bytes to capture
__WEAK void Manchester_SWO_Capture (uint8_t *buf, uint32_t num) { __WEAK void Manchester_SWO_Capture(uint8_t *buf, uint32_t num)
{
} }
// Get Manchester SWO Pending Trace Count // Get Manchester SWO Pending Trace Count
// return: number of pending trace data bytes // return: number of pending trace data bytes
__WEAK uint32_t Manchester_SWO_GetCount (void) { __WEAK uint32_t Manchester_SWO_GetCount(void)
{
return (0U);
} }
#endif /* (SWO_MANCHESTER != 0) */ #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)
if (TransferBusy != 0U) { {
if (TransferBusy != 0U)
{
SWO_AbortTransfer(); SWO_AbortTransfer();
TransferBusy = 0U; TransferBusy = 0U;
} }
@ -340,16 +416,20 @@ static void ClearTrace (void) {
} }
// Resume Trace Capture // Resume Trace Capture
static void ResumeTrace (void) { static void ResumeTrace(void)
{
uint32_t index_i; uint32_t index_i;
uint32_t index_o; uint32_t index_o;
if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED)) { if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED))
{
index_i = TraceIndexI; index_i = TraceIndexI;
index_o = TraceIndexO; index_o = TraceIndexO;
if ((index_i - index_o) < SWO_BUFFER_SIZE) { if ((index_i - index_o) < SWO_BUFFER_SIZE)
{
index_i &= SWO_BUFFER_SIZE - 1U; index_i &= SWO_BUFFER_SIZE - 1U;
switch (TraceMode) { switch (TraceMode)
{
#if (SWO_UART != 0) #if (SWO_UART != 0)
case DAP_SWO_UART: case DAP_SWO_UART:
TraceStatus = DAP_SWO_CAPTURE_ACTIVE; TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
@ -371,14 +451,18 @@ static void ResumeTrace (void) {
// Get Trace Count // Get Trace Count
// return: number of available data bytes in trace buffer // return: number of available data bytes in trace buffer
static uint32_t GetTraceCount (void) { static uint32_t GetTraceCount(void)
{
uint32_t count; uint32_t count;
if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE) { if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE)
do { {
do
{
TraceUpdate = 0U; TraceUpdate = 0U;
count = TraceIndexI - TraceIndexO; count = TraceIndexI - TraceIndexO;
switch (TraceMode) { switch (TraceMode)
{
#if (SWO_UART != 0) #if (SWO_UART != 0)
case DAP_SWO_UART: case DAP_SWO_UART:
count += UART_SWO_GetCount(); count += UART_SWO_GetCount();
@ -393,7 +477,9 @@ static uint32_t GetTraceCount (void) {
break; break;
} }
} while (TraceUpdate != 0U); } while (TraceUpdate != 0U);
} else { }
else
{
count = TraceIndexI - TraceIndexO; count = TraceIndexI - TraceIndexO;
} }
@ -402,7 +488,8 @@ static uint32_t GetTraceCount (void) {
// Get Trace Status (clear Error flags) // Get Trace Status (clear Error flags)
// return: Trace Status (Active flag and Error flags) // return: Trace Status (Active flag and Error flags)
static uint8_t GetTraceStatus (void) { static uint8_t GetTraceStatus(void)
{
uint8_t status; uint8_t status;
uint32_t n; uint32_t n;
@ -416,23 +503,26 @@ static uint8_t GetTraceStatus (void) {
// Set Trace Error flag(s) // Set Trace Error flag(s)
// flag: error flag(s) to set // flag: error flag(s) to set
static void SetTraceError (uint8_t flag) { void SetTraceError(uint8_t flag)
{
TraceError[TraceError_n] |= flag; TraceError[TraceError_n] |= flag;
} }
// Process SWO Transport command and prepare response // Process SWO Transport command and prepare response
// request: pointer to request data // request: pointer to request data
// response: pointer to response data // response: pointer to response data
// return: number of bytes in response (lower 16 bits) // return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits) // number of bytes in request (upper 16 bits)
uint32_t SWO_Transport (const uint8_t *request, uint8_t *response) { uint32_t SWO_Transport(const uint8_t *request, uint8_t *response)
{
uint8_t transport; uint8_t transport;
uint32_t result; uint32_t result;
if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U) { if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U)
{
transport = *request; transport = *request;
switch (transport) { switch (transport)
{
case 0U: case 0U:
case 1U: case 1U:
#if (SWO_STREAM != 0) #if (SWO_STREAM != 0)
@ -445,32 +535,38 @@ uint32_t SWO_Transport (const uint8_t *request, uint8_t *response) {
result = 0U; result = 0U;
break; break;
} }
} else { }
else
{
result = 0U; result = 0U;
} }
if (result != 0U) { if (result != 0U)
{
*response = DAP_OK; *response = DAP_OK;
} else { }
else
{
*response = DAP_ERROR; *response = DAP_ERROR;
} }
return ((1U << 16) | 1U); return ((1U << 16) | 1U);
} }
// Process SWO Mode command and prepare response // Process SWO Mode command and prepare response
// request: pointer to request data // request: pointer to request data
// response: pointer to response data // response: pointer to response data
// return: number of bytes in response (lower 16 bits) // return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits) // number of bytes in request (upper 16 bits)
uint32_t SWO_Mode (const uint8_t *request, uint8_t *response) { uint32_t SWO_Mode(const uint8_t *request, uint8_t *response)
{
uint8_t mode; uint8_t mode;
uint32_t result; uint32_t result;
mode = *request; mode = *request;
switch (TraceMode) { switch (TraceMode)
{
#if (SWO_UART != 0) #if (SWO_UART != 0)
case DAP_SWO_UART: case DAP_SWO_UART:
UART_SWO_Mode(0U); UART_SWO_Mode(0U);
@ -485,7 +581,8 @@ uint32_t SWO_Mode (const uint8_t *request, uint8_t *response) {
break; break;
} }
switch (mode) { switch (mode)
{
case DAP_SWO_OFF: case DAP_SWO_OFF:
result = 1U; result = 1U;
break; break;
@ -503,30 +600,36 @@ uint32_t SWO_Mode (const uint8_t *request, uint8_t *response) {
result = 0U; result = 0U;
break; break;
} }
if (result != 0U) { if (result != 0U)
{
TraceMode = mode; TraceMode = mode;
} else { }
else
{
TraceMode = DAP_SWO_OFF; TraceMode = DAP_SWO_OFF;
} }
TraceStatus = 0U; TraceStatus = 0U;
if (result != 0U) { if (result != 0U)
{
*response = DAP_OK; *response = DAP_OK;
} else { }
else
{
*response = DAP_ERROR; *response = DAP_ERROR;
} }
return ((1U << 16) | 1U); return ((1U << 16) | 1U);
} }
// Process SWO Baudrate command and prepare response // Process SWO Baudrate command and prepare response
// request: pointer to request data // request: pointer to request data
// response: pointer to response data // response: pointer to response data
// return: number of bytes in response (lower 16 bits) // return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits) // number of bytes in request (upper 16 bits)
uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response) { uint32_t SWO_Baudrate(const uint8_t *request, uint8_t *response)
{
uint32_t baudrate; uint32_t baudrate;
baudrate = (uint32_t)(*(request + 0) << 0) | baudrate = (uint32_t)(*(request + 0) << 0) |
@ -534,7 +637,8 @@ uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response) {
(uint32_t)(*(request + 2) << 16) | (uint32_t)(*(request + 2) << 16) |
(uint32_t)(*(request + 3) << 24); (uint32_t)(*(request + 3) << 24);
switch (TraceMode) { switch (TraceMode)
{
#if (SWO_UART != 0) #if (SWO_UART != 0)
case DAP_SWO_UART: case DAP_SWO_UART:
baudrate = UART_SWO_Baudrate(baudrate); baudrate = UART_SWO_Baudrate(baudrate);
@ -550,7 +654,8 @@ uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response) {
break; break;
} }
if (baudrate == 0U) { if (baudrate == 0U)
{
TraceStatus = 0U; TraceStatus = 0U;
} }
@ -562,23 +667,26 @@ uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response) {
return ((4U << 16) | 4U); return ((4U << 16) | 4U);
} }
// Process SWO Control command and prepare response // Process SWO Control command and prepare response
// request: pointer to request data // request: pointer to request data
// response: pointer to response data // response: pointer to response data
// return: number of bytes in response (lower 16 bits) // return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits) // number of bytes in request (upper 16 bits)
uint32_t SWO_Control (const uint8_t *request, uint8_t *response) { uint32_t SWO_Control(const uint8_t *request, uint8_t *response)
{
uint8_t active; uint8_t active;
uint32_t result; uint32_t result;
active = *request & DAP_SWO_CAPTURE_ACTIVE; active = *request & DAP_SWO_CAPTURE_ACTIVE;
if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)) { if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE))
if (active) { {
if (active)
{
ClearTrace(); ClearTrace();
} }
switch (TraceMode) { switch (TraceMode)
{
#if (SWO_UART != 0) #if (SWO_UART != 0)
case DAP_SWO_UART: case DAP_SWO_UART:
result = UART_SWO_Control(active); result = UART_SWO_Control(active);
@ -593,32 +701,39 @@ uint32_t SWO_Control (const uint8_t *request, uint8_t *response) {
result = 0U; result = 0U;
break; break;
} }
if (result != 0U) { if (result != 0U)
{
TraceStatus = active; TraceStatus = active;
#if (SWO_STREAM != 0) #if (SWO_STREAM != 0)
if (TraceTransport == 2U) { if (TraceTransport == 2U)
osThreadFlagsSet(SWO_ThreadId, 1U); {
xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
} }
#endif #endif
} }
} else { }
else
{
result = 1U; result = 1U;
} }
if (result != 0U) { if (result != 0U)
{
*response = DAP_OK; *response = DAP_OK;
} else { }
else
{
*response = DAP_ERROR; *response = DAP_ERROR;
} }
return ((1U << 16) | 1U); return ((1U << 16) | 1U);
} }
// Process SWO Status command and prepare response // Process SWO Status command and prepare response
// response: pointer to response data // response: pointer to response data
// return: number of bytes in response // return: number of bytes in response
uint32_t SWO_Status (uint8_t *response) { uint32_t SWO_Status(uint8_t *response)
{
uint8_t status; uint8_t status;
uint32_t count; uint32_t count;
@ -634,13 +749,13 @@ uint32_t SWO_Status (uint8_t *response) {
return (5U); return (5U);
} }
// Process SWO Extended Status command and prepare response // Process SWO Extended Status command and prepare response
// request: pointer to request data // request: pointer to request data
// response: pointer to response data // response: pointer to response data
// return: number of bytes in response (lower 16 bits) // return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits) // number of bytes in request (upper 16 bits)
uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) { uint32_t SWO_ExtendedStatus(const uint8_t *request, uint8_t *response)
{
uint8_t cmd; uint8_t cmd;
uint8_t status; uint8_t status;
uint32_t count; uint32_t count;
@ -653,13 +768,15 @@ uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) {
num = 0U; num = 0U;
cmd = *request; cmd = *request;
if (cmd & 0x01U) { if (cmd & 0x01U)
{
status = GetTraceStatus(); status = GetTraceStatus();
*response++ = status; *response++ = status;
num += 1U; num += 1U;
} }
if (cmd & 0x02U) { if (cmd & 0x02U)
{
count = GetTraceCount(); count = GetTraceCount();
*response++ = (uint8_t)(count >> 0); *response++ = (uint8_t)(count >> 0);
*response++ = (uint8_t)(count >> 8); *response++ = (uint8_t)(count >> 8);
@ -669,8 +786,10 @@ uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) {
} }
#if (TIMESTAMP_CLOCK != 0U) #if (TIMESTAMP_CLOCK != 0U)
if (cmd & 0x04U) { if (cmd & 0x04U)
do { {
do
{
TraceUpdate = 0U; TraceUpdate = 0U;
index = TraceTimestamp.index; index = TraceTimestamp.index;
tick = TraceTimestamp.tick; tick = TraceTimestamp.tick;
@ -690,13 +809,13 @@ uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) {
return ((1U << 16) | num); return ((1U << 16) | num);
} }
// Process SWO Data command and prepare response // Process SWO Data command and prepare response
// request: pointer to request data // request: pointer to request data
// response: pointer to response data // response: pointer to response data
// return: number of bytes in response (lower 16 bits) // return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits) // number of bytes in request (upper 16 bits)
uint32_t SWO_Data (const uint8_t *request, uint8_t *response) { uint32_t SWO_Data(const uint8_t *request, uint8_t *response)
{
uint8_t status; uint8_t status;
uint32_t count; uint32_t count;
uint32_t index; uint32_t index;
@ -705,16 +824,21 @@ uint32_t SWO_Data (const uint8_t *request, uint8_t *response) {
status = GetTraceStatus(); status = GetTraceStatus();
count = GetTraceCount(); count = GetTraceCount();
if (TraceTransport == 1U) { if (TraceTransport == 1U)
{
n = (uint32_t)(*(request + 0) << 0) | n = (uint32_t)(*(request + 0) << 0) |
(uint32_t)(*(request + 1) << 8); (uint32_t)(*(request + 1) << 8);
if (n > (DAP_PACKET_SIZE - 4U)) { if (n > (DAP_PACKET_SIZE - 4U))
{
n = DAP_PACKET_SIZE - 4U; n = DAP_PACKET_SIZE - 4U;
} }
if (count > n) { if (count > n)
{
count = n; count = n;
} }
} else { }
else
{
count = 0U; count = 0U;
} }
@ -722,9 +846,11 @@ uint32_t SWO_Data (const uint8_t *request, uint8_t *response) {
*response++ = (uint8_t)(count >> 0); *response++ = (uint8_t)(count >> 0);
*response++ = (uint8_t)(count >> 8); *response++ = (uint8_t)(count >> 8);
if (TraceTransport == 1U) { if (TraceTransport == 1U)
{
index = TraceIndexO; index = TraceIndexO;
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++ = TraceBuf[i++];
} }
@ -735,19 +861,20 @@ uint32_t SWO_Data (const uint8_t *request, uint8_t *response) {
return ((2U << 16) | (3U + count)); return ((2U << 16) | (3U + count));
} }
#if (SWO_STREAM != 0) #if (SWO_STREAM != 0)
// SWO Data Transfer complete callback // SWO Data Transfer complete callback
void SWO_TransferComplete (void) { void SWO_TransferComplete(void)
{
TraceIndexO += TransferSize; TraceIndexO += TransferSize;
TransferBusy = 0U; TransferBusy = 0U;
ResumeTrace(); ResumeTrace();
osThreadFlagsSet(SWO_ThreadId, 1U); xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
} }
// SWO Thread // SWO Thread
__NO_RETURN void SWO_Thread (void *argument) { void SWO_Thread(void *argument)
{
uint32_t timeout; uint32_t timeout;
uint32_t flags; uint32_t flags;
uint32_t count; uint32_t count;
@ -755,41 +882,59 @@ __NO_RETURN void SWO_Thread (void *argument) {
uint32_t i, n; uint32_t i, n;
(void)argument; (void)argument;
timeout = osWaitForever; timeout = portMAX_DELAY;
for (;;) { kSWO_Thread_event_group = xEventGroupCreate();
flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout); for (;;)
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { {
flags = xEventGroupWaitBits(kSWO_Thread_event_group, SWO_GOT_DATA | SWO_ERROR_TIME_OUT,
pdTRUE, pdFALSE, timeout);
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
{
timeout = SWO_STREAM_TIMEOUT; timeout = SWO_STREAM_TIMEOUT;
} else {
timeout = osWaitForever;
flags = osFlagsErrorTimeout;
} }
if (TransferBusy == 0U) { else
{
timeout = portMAX_DELAY;
flags = SWO_ERROR_TIME_OUT;
}
if (TransferBusy == 0U)
{
count = GetTraceCount(); count = GetTraceCount();
if (count != 0U) { if (count != 0U)
{
index = TraceIndexO & (SWO_BUFFER_SIZE - 1U); index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
n = SWO_BUFFER_SIZE - index; n = SWO_BUFFER_SIZE - index;
if (count > n) { if (count > n)
{
count = n; count = n;
} }
if (flags != osFlagsErrorTimeout) { if ((flags & SWO_ERROR_TIME_OUT) == 0)
{
i = index & (USB_BLOCK_SIZE - 1U); i = index & (USB_BLOCK_SIZE - 1U);
if (i == 0U) { if (i == 0U)
{
count &= ~(USB_BLOCK_SIZE - 1U); count &= ~(USB_BLOCK_SIZE - 1U);
} else { // Take down to the nearest number that is a multiple of USB_BLOCK_SIZE
}
else
{
n = USB_BLOCK_SIZE - i; n = USB_BLOCK_SIZE - i;
if (count >= n) { if (count >= n)
{
count = n; count = n;
} else { }
else
{
count = 0U; count = 0U;
} }
} }
} }
if (count != 0U) { if (count != 0U)
{
TransferSize = count; TransferSize = count;
TransferBusy = 1U; TransferBusy = 1U;
SWO_QueueTransfer(&TraceBuf[index], count); SWO_QueueTransfer(&TraceBuf[index], count); //through USB
} }
} }
} }
@ -798,5 +943,4 @@ __NO_RETURN void SWO_Thread (void *argument) {
#endif /* (SWO_STREAM != 0) */ #endif /* (SWO_STREAM != 0) */
#endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */ #endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */

File diff suppressed because it is too large Load Diff

View File

@ -16,30 +16,68 @@
////TODO: Merge this ////TODO: Merge this
#define DAP_PACKET_SIZE 512 #define DAP_PACKET_SIZE 512
static uint8_t data_out[DAP_PACKET_SIZE];
static int dap_respond = 0;
uint8_t data_out[DAP_PACKET_SIZE]; // SWO Trace
int respond = 0; static int swo_trace_respond = 0;
static uint8_t *swo_data_to_send;
static uint32_t num_swo_data;
void handle_dap_data_request(usbip_stage2_header *header) void handle_dap_data_request(usbip_stage2_header *header)
{ {
uint8_t *data_in = (uint8_t *)header; uint8_t *data_in = (uint8_t *)header;
data_in = &(data_in[sizeof(usbip_stage2_header)]); data_in = &(data_in[sizeof(usbip_stage2_header)]);
// Point to the beginning of the URB packet // Point to the beginning of the URB packet
respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out); dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out);
send_stage2_submit(header, 0, 0); send_stage2_submit(header, 0, 0);
} }
void handle_dap_data_response(usbip_stage2_header *header) void handle_dap_data_response(usbip_stage2_header *header)
{ {
if (respond) { if (dap_respond)
respond = 0; {
dap_respond = 0;
//os_printf("*** Will respond"); //os_printf("*** Will respond");
send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE); send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE);
//os_printf("*** RESPONDED ***"); //os_printf("*** RESPONDED ***");
} else { }
else
{
//os_printf("*** Will NOT respond"); //os_printf("*** Will NOT respond");
send_stage2_submit(header, 0, 0); send_stage2_submit(header, 0, 0);
} }
} }
void handle_swo_trace_response(usbip_stage2_header *header)
{
if (swo_trace_respond)
{
swo_trace_respond = 0;
//os_printf("*** Will respond");
send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE);
//os_printf("*** RESPONDED ***");
}
else
{
//os_printf("*** Will NOT respond");
send_stage2_submit(header, 0, 0);
}
}
// SWO Data Queue Transfer
// buf: pointer to buffer with data
// num: number of bytes to transfer
void SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
swo_data_to_send = buf;
num_swo_data = num;
swo_trace_respond = 1;
}
// SWO Data Abort Transfer
void SWO_AbortTransfer (void) {
//USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
////TODO: unlink might be useful ...
}

View File

@ -5,4 +5,5 @@
void handle_dap_data_request(usbip_stage2_header *header); void handle_dap_data_request(usbip_stage2_header *header);
void handle_dap_data_response(usbip_stage2_header *header); void handle_dap_data_response(usbip_stage2_header *header);
void handle_swo_trace_response(usbip_stage2_header *header);
#endif #endif

View File

@ -26,13 +26,14 @@
#include "tcp_server.h" #include "tcp_server.h"
#include "timer.h" #include "timer.h"
#include "wifi_configuration.h" #include "wifi_configuration.h"
/* The examples use simple WiFi configuration that you can set via /* The examples use simple WiFi configuration that you can set via
'make menuconfig'. 'make menuconfig'.
If you'd rather not, just change the below entries to strings with If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/ */
extern void SWO_Thread(void *argument);
extern void usart_monitor_task(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;
@ -95,6 +96,7 @@ 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));
@ -135,6 +137,10 @@ void app_main()
initialise_wifi(); initialise_wifi();
wait_for_ip(); wait_for_ip();
xTaskCreate(timer_create_task, "timer_create", 1024, NULL, 10, NULL); xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL);
xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL); xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL);
// SWO Trace Task
xTaskCreate(SWO_Thread, "swo_task", 1024, NULL, 6, NULL);
xTaskCreate(usart_monitor_task, "uart_task", 512, NULL, 6, NULL);
} }

View File

@ -27,6 +27,10 @@ static void unpack(void *data, int size);
static int handle_submit(usbip_stage2_header *header); static int handle_submit(usbip_stage2_header *header);
static int read_stage2_command(usbip_stage2_header *header, uint32_t length); static int read_stage2_command(usbip_stage2_header *header, uint32_t length);
static void handle_unlink(usbip_stage2_header *header);
// unlink helper function
static void send_stage2_unlink(usbip_stage2_header *req_header);
int attach(uint8_t *buffer, uint32_t length) int attach(uint8_t *buffer, uint32_t length)
{ {
int command = read_stage1_command(buffer, length); int command = read_stage1_command(buffer, length);
@ -258,7 +262,6 @@ static void unpack(void *data, int size)
} }
} }
/** /**
* @brief * @brief
* *
@ -272,7 +275,7 @@ static int handle_submit(usbip_stage2_header *header)
handleUSBControlRequest(header); handleUSBControlRequest(header);
break; break;
// data // endpoint 1 data receicve and response
case 0x01: case 0x01:
if (header->base.direction == 0) if (header->base.direction == 0)
{ {
@ -285,7 +288,19 @@ static int handle_submit(usbip_stage2_header *header)
handle_dap_data_response(header); handle_dap_data_response(header);
} }
break; break;
// endpoint 2 for SWO trace
case 0x02:
if (header->base.direction == 0)
{
// os_printf("EP 02 DATA FROM HOST");
send_stage2_submit(header, 0, 0);
}
else
{
// os_printf("EP 02 DATA TO HOST");
handle_swo_trace_response(header);
}
break;
// request to save data to device // request to save data to device
case 0x81: case 0x81:
if (header->base.direction == 0) if (header->base.direction == 0)
@ -330,3 +345,23 @@ void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, co
send(kSock, data, data_length, 0); send(kSock, data, data_length, 0);
} }
} }
static void handle_unlink(usbip_stage2_header *header)
{
os_printf("s2 handling cmd unlink...\r\n");
send_stage2_unlink(header);
}
static void send_stage2_unlink(usbip_stage2_header *req_header)
{
req_header->base.command = USBIP_STAGE2_RSP_UNLINK;
req_header->base.direction = USBIP_DIR_OUT;
memset(&(req_header->u.ret_unlink), 0, sizeof(usbip_stage2_header_ret_unlink));
// req_header.u.ret_unlink.status = 0;
pack(req_header, sizeof(usbip_stage2_header));
send(kSock, req_header, sizeof(usbip_stage2_header), 0);
}