From f37af779bb836faa7571b7d47036f36f71319aca Mon Sep 17 00:00:00 2001 From: lonkaars Date: Fri, 28 Oct 2022 11:29:09 +0200 Subject: use circular dma buffer for rx --- stm32f091/consts.h | 4 ++-- stm32f091/esp8266.c | 36 ++++++++++++++++++++++-------------- stm32f091/esp8266.h | 7 ++----- stm32f091/server.c | 3 +-- stm32f091/setup.c | 2 +- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/stm32f091/consts.h b/stm32f091/consts.h index 0a8acec..3d2ef5a 100644 --- a/stm32f091/consts.h +++ b/stm32f091/consts.h @@ -3,10 +3,10 @@ #include "wifi.h" #define WS_SERVER_PORT "80" -#define WS_SERVER_MAX_CHANNELS 2 +#define WS_SERVER_MAX_CHANNELS 4 #define WS_DMA_RX_BUFFER_SIZE 100 -#define WS_DMA_TX_BUFFER_SIZE 100 +#define WS_DMA_TX_BUFFER_SIZE 1024 #define WS_PINOUT_I2C_SDA_PIN GPIO_PIN_9 #define WS_PINOUT_I2C_SDA_PORT GPIOB diff --git a/stm32f091/esp8266.c b/stm32f091/esp8266.c index db134a0..754b45b 100644 --- a/stm32f091/esp8266.c +++ b/stm32f091/esp8266.c @@ -17,6 +17,8 @@ } uint8_t g_ws_esp8266_dma_rx_buffer[WS_DMA_RX_BUFFER_SIZE]; +unsigned int g_ws_esp8266_dma_rx_head = 0; +unsigned int g_ws_esp8266_dma_rx_tail = 0; uint8_t g_ws_esp8266_dma_tx_buffer[WS_DMA_TX_BUFFER_SIZE]; void DMA1_Ch1_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_usart1_rx); } @@ -24,19 +26,30 @@ void DMA1_Ch2_3_DMA2_Ch1_2_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_usart1_tx void USART1_IRQHandler(void) { if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG(&huart1); - HAL_UART_RxCpltCallback(&huart1); - HAL_UART_DMAStop(&huart1); - ws_esp8266_start_receive(); + // https://stackoverflow.com/questions/71039052/hal-uartex-rxeventcallback-circular-dma-what-address-is-the-data + g_ws_esp8266_dma_rx_head = huart1.RxXferSize - huart1.hdmarx->Instance->CNDTR; + + ws_esp8266_incoming_data_chunk(); } HAL_UART_IRQHandler(&huart1); } -void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart) { - size_t len = strlen((char*) g_ws_esp8266_dma_rx_buffer); - if (len > 0) ws_server_req_incoming(g_ws_esp8266_dma_rx_buffer, len); - - memset(g_ws_esp8266_dma_rx_buffer, 0, WS_DMA_RX_BUFFER_SIZE); - ws_esp8266_start_receive(); +void ws_esp8266_incoming_data_chunk() { + if (g_ws_esp8266_dma_rx_head == g_ws_esp8266_dma_rx_tail) return; // no new data + if (g_ws_esp8266_dma_rx_head > g_ws_esp8266_dma_rx_tail) { + // read from tail until head + ws_server_req_incoming(&g_ws_esp8266_dma_rx_buffer[g_ws_esp8266_dma_rx_tail], + g_ws_esp8266_dma_rx_head - g_ws_esp8266_dma_rx_tail); + } else /* if (g_ws_esp8266_dma_rx_head < g_ws_esp8266_dma_rx_tail) */ { + // read from tail until end of buffer + ws_server_req_incoming(&g_ws_esp8266_dma_rx_buffer[g_ws_esp8266_dma_rx_tail], + WS_DMA_RX_BUFFER_SIZE - g_ws_esp8266_dma_rx_tail); + // read from buffer begin until head + ws_server_req_incoming(&g_ws_esp8266_dma_rx_buffer[0], // yes i know this looks dumb + g_ws_esp8266_dma_rx_head); + } + // finish read by shifting tail forward + g_ws_esp8266_dma_rx_tail = g_ws_esp8266_dma_rx_head; } void ws_esp8266_send(uint8_t* data, size_t size) { @@ -54,11 +67,6 @@ void ws_esp8266_send(uint8_t* data, size_t size) { __HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE); } -void ws_esp8266_start_receive() { - HAL_UART_Receive_DMA(&huart1, g_ws_esp8266_dma_rx_buffer, WS_DMA_RX_BUFFER_SIZE); - __HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT); -} - void ws_esp8266_connect() { ws_esp8266_send_seq("AT+CWJAP=\"" WS_ESP8266_WLAN_SSID "\",\"" WS_ESP8266_WLAN_PASSWD "\"\r\n"); } diff --git a/stm32f091/esp8266.h b/stm32f091/esp8266.h index 66ccfba..94a7356 100644 --- a/stm32f091/esp8266.h +++ b/stm32f091/esp8266.h @@ -19,14 +19,11 @@ void DMA1_Ch1_IRQHandler(void); /** @brief USART1 interrupt handler */ void USART1_IRQHandler(void); -/** @brief receive chunk complete */ -void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart); - /** @brief send data to esp over uart with dma */ void ws_esp8266_send(uint8_t* data, size_t size); -/** @brief start dma receive and reset half-transfer interrupt flag */ -void ws_esp8266_start_receive(); +/** @brief line idle, handle new data on dma buffer */ +void ws_esp8266_incoming_data_chunk(); /** @brief connect to access point using wifi.h credentials */ void ws_esp8266_connect(); diff --git a/stm32f091/server.c b/stm32f091/server.c index d4f7e20..8001380 100644 --- a/stm32f091/server.c +++ b/stm32f091/server.c @@ -127,9 +127,8 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { } case WS_SERVER_LM_CIPSEND_LISTENING: { if (next_few_bytes_are("SEND OK")) { - i += 6; - // g_ws_server_parser.mode = WS_SERVER_LM_IDLE; ws_server_req_respond_end(0); + // g_ws_server_parser.mode = WS_SERVER_LM_IDLE; } break; } diff --git a/stm32f091/setup.c b/stm32f091/setup.c index 1971809..3bf331f 100644 --- a/stm32f091/setup.c +++ b/stm32f091/setup.c @@ -53,7 +53,7 @@ DMA_HandleTypeDef hdma_usart1_rx = { .Init.MemInc = DMA_MINC_ENABLE, .Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE, .Init.MemDataAlignment = DMA_MDATAALIGN_BYTE, - .Init.Mode = DMA_NORMAL, + .Init.Mode = DMA_CIRCULAR, .Init.Priority = DMA_PRIORITY_LOW, }; -- cgit v1.2.3