From 94e31069df88c3d5e50b4160705c2b7aa27e152b Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 27 Oct 2022 15:37:35 +0200 Subject: WIP server parser --- stm32f091/consts.h | 6 +++-- stm32f091/esp8266.c | 27 ++++++++++++++++--- stm32f091/esp8266.h | 6 ++--- stm32f091/server.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++----- stm32f091/server.h | 27 +++++++++++++++++++ stm32f091/setup.c | 5 +++- stm32f091/test.c | 15 +++++++---- 7 files changed, 139 insertions(+), 21 deletions(-) diff --git a/stm32f091/consts.h b/stm32f091/consts.h index 5f9d7a1..b3bc2e2 100644 --- a/stm32f091/consts.h +++ b/stm32f091/consts.h @@ -4,8 +4,8 @@ #define WS_SERVER_PORT "80" -#define WS_DMA_RX_BUFFER_SIZE 10 -#define WS_DMA_TX_BUFFER_SIZE 50 +#define WS_DMA_RX_BUFFER_SIZE 100 +#define WS_DMA_TX_BUFFER_SIZE 100 #define WS_PINOUT_I2C_SDA_PIN GPIO_PIN_9 #define WS_PINOUT_I2C_SDA_PORT GPIOB @@ -22,3 +22,5 @@ #define WS_PINOUT_USART2_TX_PIN GPIO_PIN_2 #define WS_PINOUT_USART2_TX_PORT GPIOA +// print esp communication over usb serial (green for tx, red for rx) +#define WS_DBG_PRINT_ESP_OVER_USART2 diff --git a/stm32f091/esp8266.c b/stm32f091/esp8266.c index 4daba34..c98528e 100644 --- a/stm32f091/esp8266.c +++ b/stm32f091/esp8266.c @@ -15,13 +15,22 @@ uint8_t g_ws_esp8266_dma_tx_buffer[WS_DMA_TX_BUFFER_SIZE]; void DMA1_Ch1_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_usart1_rx); } void DMA1_Ch2_3_DMA2_Ch1_2_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_usart1_tx); } -void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); } +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(); + } + HAL_UART_IRQHandler(&huart1); +} void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart) { - ws_server_req_incoming(g_ws_esp8266_dma_rx_buffer, WS_DMA_RX_BUFFER_SIZE); + 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); - 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); + memset(g_ws_esp8266_dma_rx_buffer, 0, WS_DMA_RX_BUFFER_SIZE); + ws_esp8266_start_receive(); } void ws_esp8266_send(uint8_t* data, size_t size) { @@ -29,10 +38,20 @@ void ws_esp8266_send(uint8_t* data, size_t size) { memcpy(g_ws_esp8266_dma_tx_buffer, data, limited_size); g_ws_esp8266_dma_tx_buffer[limited_size] = 0x00; +#ifdef WS_DBG_PRINT_ESP_OVER_USART2 + uint8_t green[] = { 0x1b, 0x5b, 0x33, 0x32, 0x6d }; + HAL_UART_Transmit(&huart2, green, sizeof(green), 100); + HAL_UART_Transmit(&huart2, g_ws_esp8266_dma_tx_buffer, strlen((char*) g_ws_esp8266_dma_tx_buffer), 100); +#endif + HAL_UART_Transmit_DMA(&huart1, g_ws_esp8266_dma_tx_buffer, strlen((char*) g_ws_esp8266_dma_tx_buffer)); __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); +} // TODO: refactor code from here to EOF void ws_esp8266_ATsendCommand(uint8_t* data){ diff --git a/stm32f091/esp8266.h b/stm32f091/esp8266.h index 0832e95..64910fd 100644 --- a/stm32f091/esp8266.h +++ b/stm32f091/esp8266.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "consts.h" @@ -21,12 +22,11 @@ void USART1_IRQHandler(void); /** @brief receive chunk complete */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart); -/** @brief send response to incoming request on specific channel */ -void ws_esp8266_res_send(unsigned int channel, uint8_t* data, size_t size); - /** @brief send data to esp over uart with dma */ void ws_esp8266_send(uint8_t* data, size_t size); +void ws_esp8266_start_receive(); + // TODO: remove/update/document/refactor these functions void ws_esp8266_ATsendCommand(uint8_t* data); int ws_esp8266_checkOK(uint8_t *receiveData,int length); diff --git a/stm32f091/server.c b/stm32f091/server.c index de6ea50..aa2ff8b 100644 --- a/stm32f091/server.c +++ b/stm32f091/server.c @@ -3,15 +3,77 @@ #include #include +#include "esp8266.h" #include "server.h" +#include "setup.h" +#include "consts.h" +static ws_s_server_parser g_ws_server_parser = { + .counter = 0, + .last_response = WS_SERVER_RC_NONE, + .mode = WS_SERVER_LM_IDLE, +}; + +// TODO: next_few_bytes_are assumes that the complete search string is in the +// buffer, so won't work for buffer cutoffs +#define next_few_bytes_are(code) (i + sizeof(code) - 1 < size && strncmp((char*)&data[i], code, sizeof(code) - 1) == 0) void ws_server_req_incoming(uint8_t* data, size_t size) { - // TODO: server req incoming implementation - // - // example +IPD command: - // +IPD,0,15:last-records 5\n - // - // TODO: protocol req response parser -> (ws_esp8622_at_send(data, channel) ?) +#ifdef WS_DBG_PRINT_ESP_OVER_USART2 + uint8_t red[] = { 0x1b, 0x5b, 0x33, 0x31, 0x6d }; + HAL_UART_Transmit(&huart2, red, sizeof(red), 100); + HAL_UART_Transmit(&huart2, data, size, 100); +#endif + + for (unsigned int i = 0; i < size; i++) { + uint8_t byte = data[i]; + + switch (g_ws_server_parser.mode) { + case WS_SERVER_LM_CMD_ECHO: { + if (byte == '\n') g_ws_server_parser.mode = WS_SERVER_LM_STATUS_CODE; + break; + } + case WS_SERVER_LM_STATUS_CODE: { + bool code_got = false; + if (next_few_bytes_are("OK")) { + code_got = true; + g_ws_server_parser.last_response = WS_SERVER_RC_OK; + } else if (next_few_bytes_are("ERROR")) { + code_got = true; + g_ws_server_parser.last_response = WS_SERVER_RC_ERR; + } else if (next_few_bytes_are("busy p...")) { + code_got = true; + g_ws_server_parser.last_response = WS_SERVER_RC_BUSY; + } + if (code_got) g_ws_server_parser.mode = WS_SERVER_LM_IDLE; + break; + } + case WS_SERVER_LM_IDLE: { + if (next_few_bytes_are("+IPD")) { + i += 3; // skip I, P, and D + g_ws_server_parser.mode = WS_SERVER_LM_IPD_LISTENING; + } + break; + } + case WS_SERVER_LM_IPD_LISTENING: { + // +IPD,0,15:last-records 5\n + break; + } + default: {} + } + } return; } + +void ws_server_send(uint8_t* data, size_t size) { + g_ws_server_parser.mode = WS_SERVER_LM_CMD_ECHO; + ws_esp8266_send(data, size); + while (g_ws_server_parser.mode != WS_SERVER_LM_IDLE) {}; +} + +void ws_server_req_respond(unsigned int channel, uint8_t* data, size_t size) { + uint8_t Tx_close[]="AT+CIPCLOSE=0\r\n"; + uint8_t Tx_send[]="AT+CIPSEND=0,LEN:"; + return; +} + diff --git a/stm32f091/server.h b/stm32f091/server.h index 6041ef6..c5698c0 100644 --- a/stm32f091/server.h +++ b/stm32f091/server.h @@ -2,6 +2,27 @@ #include #include +#include + +typedef enum { + WS_SERVER_LM_CMD_ECHO, /** @brief listen for echo of sent command */ + WS_SERVER_LM_STATUS_CODE, /** @brief listen for busy, ERROR or OK */ + WS_SERVER_LM_IDLE, /** @brief listen for incoming +IPD commands */ + WS_SERVER_LM_IPD_LISTENING, /** @brief +IPD received, now reading data */ +} ws_e_server_listen_mode; + +typedef enum { + WS_SERVER_RC_NONE = -1, + WS_SERVER_RC_BUSY, + WS_SERVER_RC_ERR, + WS_SERVER_RC_OK, +} ws_e_server_response_code; + +typedef struct { + int counter; + ws_e_server_listen_mode mode; + ws_e_server_response_code last_response; +} ws_s_server_parser; /** * @brief +IPD incoming request handler @@ -15,3 +36,9 @@ */ void ws_server_req_incoming(uint8_t* data, size_t size); +/** @brief send response to incoming request on specific channel */ +void ws_server_req_respond(unsigned int channel, uint8_t* data, size_t size); + +/** @brief send data to esp, waiting until server returns to idle mode */ +void ws_server_send(uint8_t* data, size_t size); + diff --git a/stm32f091/setup.c b/stm32f091/setup.c index 2110e03..9ed4174 100644 --- a/stm32f091/setup.c +++ b/stm32f091/setup.c @@ -133,12 +133,15 @@ static void ws_io_usart1_setup() { 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); + + __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); // enable receive intterupts + __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // enable idle line detection } static void ws_io_usart2_setup() { if (HAL_UART_Init(&huart2) != HAL_OK) return ws_setup_error_handler(); -} +} static void ws_io_dma_setup() { __HAL_RCC_DMA1_CLK_ENABLE(); diff --git a/stm32f091/test.c b/stm32f091/test.c index e25b071..c5e43da 100644 --- a/stm32f091/test.c +++ b/stm32f091/test.c @@ -2,13 +2,18 @@ #include #include -#include "esp8266.h" +#include "server.h" +#include "setup.h" void ws_test_write_task() { - uint8_t data[] = "AT\r\n"; + // uint8_t data[] = "AT+CIPMUX=1+CWMODE=1+CWJAP=\"" WS_ESP8266_WLAN_SSID "\",\"" WS_ESP8266_WLAN_PASSWD "\"\r\n"; + uint8_t cmd1[] = "AT+CIPMUX=1\r\n"; + uint8_t cmd2[] = "AT+CWMODE=1\r\n"; + uint8_t cmd3[] = "AT+CWJAP=\"" WS_ESP8266_WLAN_SSID "\",\"" WS_ESP8266_WLAN_PASSWD "\"\r\n"; while (1) { - ws_esp8266_send(data, sizeof(data)); - - vTaskDelay(portTICK_PERIOD_MS * 100 * 1); + ws_server_send(cmd1, sizeof(cmd1)); + ws_server_send(cmd2, sizeof(cmd2)); + ws_server_send(cmd3, sizeof(cmd3)); + vTaskDelay(portTICK_PERIOD_MS * 1000 * 1); } } -- cgit v1.2.3