From 3425a00d6ce3dcad23ba43a79738b3d5b9ae1967 Mon Sep 17 00:00:00 2001 From: Evlers <35098087+Evlers@users.noreply.github.com> Date: Wed, 11 Sep 2024 23:06:25 +0800 Subject: [PATCH] fix: HSLink Pro delay issues for uart rx to usb (#16) --- projects/HSLink-Pro/src/main.c | 2 + projects/HSLink-Pro/src/usb2uart.c | 70 ++++++++++++++++++------------ 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/projects/HSLink-Pro/src/main.c b/projects/HSLink-Pro/src/main.c index 1701a82..25153b9 100644 --- a/projects/HSLink-Pro/src/main.c +++ b/projects/HSLink-Pro/src/main.c @@ -8,6 +8,7 @@ #include "projects/HSLink-Pro/common/HSLink_Pro_expansion.h" extern void uartx_preinit(void); +extern void usb2uart_handler (void); char serial_number[32]; @@ -61,6 +62,7 @@ int main(void) while (1) { chry_dap_handle(); chry_dap_usb2uart_handle(); + usb2uart_handler(); HSP_Loop(); } } diff --git a/projects/HSLink-Pro/src/usb2uart.c b/projects/HSLink-Pro/src/usb2uart.c index ca7f688..30f7545 100644 --- a/projects/HSLink-Pro/src/usb2uart.c +++ b/projects/HSLink-Pro/src/usb2uart.c @@ -16,19 +16,19 @@ #define UART_TX_DMA HPM_DMA_SRC_UART2_TX #define UART_TX_DMA_RESOURCE_INDEX (1U) -#define UART_TX_DMA_BUFFER_SIZE (8192U) +// #define UART_TX_DMA_BUFFER_SIZE (8192U) -ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(4) -uint8_t uart_tx_buf[UART_TX_DMA_BUFFER_SIZE]; +static uint32_t rb_write_pos = 0; +// ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(4) +// uint8_t uart_tx_buf[UART_TX_DMA_BUFFER_SIZE]; ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(4) uint8_t uart_rx_buf[UART_RX_DMA_BUFFER_COUNT][UART_RX_DMA_BUFFER_SIZE]; ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(8) -dma_linked_descriptor_t rx_descriptors[UART_RX_DMA_BUFFER_COUNT - 1]; +dma_linked_descriptor_t rx_descriptors[UART_RX_DMA_BUFFER_COUNT]; static dma_resource_t dma_resource_pools[2]; volatile uint32_t g_uart_tx_transfer_length = 0; static hpm_stat_t board_uart_dma_config(void); -static hpm_stat_t board_uart_rx_dma_restart(void); void dma_channel_tc_callback(DMA_Type *ptr, uint32_t channel, void *user_data) { @@ -41,13 +41,10 @@ void dma_channel_tc_callback(DMA_Type *ptr, uint32_t channel, void *user_data) uint32_t link_addr = ptr->CHCTRL[channel].LLPOINTER; uint32_t rx_desc_size = (sizeof(rx_descriptors) / sizeof(dma_linked_descriptor_t)); if (rx_resource->channel == channel) { - if (link_addr == (uint32_t)NULL) { - board_uart_rx_dma_restart(); - return; - } for (i = 0; i < rx_desc_size; i++) { if (link_addr == core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)&rx_descriptors[i])) { - chry_ringbuffer_write(&g_uartrx, uart_rx_buf[i - 1], UART_RX_DMA_BUFFER_SIZE); + chry_ringbuffer_write(&g_uartrx, &uart_rx_buf[i][rb_write_pos], UART_RX_DMA_BUFFER_SIZE - rb_write_pos); + rb_write_pos = 0; } } } @@ -69,8 +66,8 @@ void uart_isr(void) if (uart_received_data_count > 0) { for (i = 0; i < rx_desc_size; i++) { if (link_addr == core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)&rx_descriptors[i])) { - chry_ringbuffer_write(&g_uartrx, uart_rx_buf[i], uart_received_data_count); - board_uart_rx_dma_restart(); + chry_ringbuffer_write(&g_uartrx, &uart_rx_buf[i][rb_write_pos], uart_received_data_count - rb_write_pos); + rb_write_pos += uart_received_data_count - rb_write_pos; break; } } @@ -79,6 +76,37 @@ void uart_isr(void) } SDK_DECLARE_EXT_ISR_M(UART_IRQ, uart_isr) +void usb2uart_handler (void) +{ + dma_resource_t *rx_resource = &dma_resource_pools[UART_RX_DMA_RESOURCE_INDEX]; + const uint32_t rx_desc_size = (sizeof(rx_descriptors) / sizeof(dma_linked_descriptor_t)); + uint32_t uart_received_data_count = UART_RX_DMA_BUFFER_SIZE - dma_get_remaining_transfer_size(rx_resource->base, rx_resource->channel); + + if ((uart_received_data_count - rb_write_pos) > 0) + { + uint32_t level = disable_global_irq(CSR_MSTATUS_MIE_MASK); + uint32_t link_addr = rx_resource->base->CHCTRL[rx_resource->channel].LLPOINTER; + + /* data may be preempted by interrupts, need to reread the count */ + uart_received_data_count = UART_RX_DMA_BUFFER_SIZE - dma_get_remaining_transfer_size(rx_resource->base, rx_resource->channel); + + if ((uart_received_data_count - rb_write_pos) > 0) + { + for (int i = 0; i < rx_desc_size; i++) + { + if (link_addr == core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)&rx_descriptors[i])) + { + chry_ringbuffer_write(&g_uartrx, &uart_rx_buf[i][rb_write_pos], uart_received_data_count - rb_write_pos); + rb_write_pos += uart_received_data_count - rb_write_pos; + break; + } + } + } + + restore_global_irq(level); + } +} + void uartx_preinit(void) { // board_init_uart(UART_BASE); @@ -131,18 +159,6 @@ void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len) dma_mgr_enable_channel(tx_resource); } -static hpm_stat_t board_uart_rx_dma_restart(void) -{ - dma_resource_t *resource = &dma_resource_pools[UART_RX_DMA_RESOURCE_INDEX]; - dma_mgr_disable_channel(resource); - uint32_t addr = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)uart_rx_buf[0]); - dma_mgr_set_chn_dst_addr(resource, addr); - addr = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)&rx_descriptors[0]); - resource->base->CHCTRL[resource->channel].LLPOINTER = addr; - dma_mgr_set_chn_transize(resource, UART_RX_DMA_BUFFER_SIZE); - dma_mgr_enable_channel(resource); - return status_success; -} static hpm_stat_t board_uart_dma_config(void) { dma_mgr_chn_conf_t chg_config; @@ -165,10 +181,10 @@ static hpm_stat_t board_uart_dma_config(void) chg_config.dmamux_src = UART_RX_DMA; for (i = 0; i < rx_desc_size; i++) { if (i < (rx_desc_size - 1)) { - chg_config.dst_addr = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)uart_rx_buf[i + 1]); - chg_config.linked_ptr = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)&rx_descriptors[i + 1]); + chg_config.dst_addr = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)uart_rx_buf[i]); + chg_config.linked_ptr = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)&rx_descriptors[i]); } else { - chg_config.dst_addr = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)uart_rx_buf[1]); + chg_config.dst_addr = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)uart_rx_buf[0]); chg_config.linked_ptr = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)&rx_descriptors[0]); } if (dma_mgr_config_linked_descriptor(resource, &chg_config, (dma_mgr_linked_descriptor_t *)&rx_descriptors[i]) != status_success) {