From 0b05974d6462780030802a2991a9c929059b722a Mon Sep 17 00:00:00 2001 From: lonkaars Date: Fri, 14 Oct 2022 14:11:23 +0200 Subject: add printf macro util.h --- stm32f091/util.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 stm32f091/util.h (limited to 'stm32f091/util.h') diff --git a/stm32f091/util.h b/stm32f091/util.h new file mode 100644 index 0000000..8e3258f --- /dev/null +++ b/stm32f091/util.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include +#include +#include + +#include "setup.h" + +#define ws_usb_printf(fmt, ...) { \ + char temp[255]; \ + sprintf(temp, fmt, ##__VA_ARGS__); \ + HAL_UART_Transmit(&huart2, (uint8_t*) temp, sizeof(char) * strlen(temp), HAL_MAX_DELAY); \ +} + -- cgit v1.2.3 From aab4ed17b94f54813368201d3a0cba3f3d432589 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Wed, 19 Oct 2022 20:04:06 +0200 Subject: integrate protocol code into stm32 code --- shared/backlog.c | 47 ---------------------------- shared/backlog.h | 59 ----------------------------------- shared/makefile | 24 --------------- shared/protocol.c | 87 ++++++++++++++++++++++++++-------------------------- shared/protocol.md | 7 +++-- shared/shared.mk | 1 + shared/test.c | 82 ------------------------------------------------- shared/testcmd | 1 - stm32f091/backlog.c | 5 --- stm32f091/esp8266.c | 7 +++-- stm32f091/main.c | 1 - stm32f091/makefile | 8 +++++ stm32f091/protocol.c | 33 ++++++++++++++++++++ stm32f091/sensor.c | 6 ++++ stm32f091/server.c | 2 +- stm32f091/util.h | 3 +- 16 files changed, 103 insertions(+), 270 deletions(-) delete mode 100644 shared/backlog.c delete mode 100644 shared/backlog.h delete mode 100644 shared/makefile create mode 100644 shared/shared.mk delete mode 100644 shared/test.c delete mode 100644 shared/testcmd create mode 100644 stm32f091/protocol.c (limited to 'stm32f091/util.h') diff --git a/shared/backlog.c b/shared/backlog.c deleted file mode 100644 index 926ccad..0000000 --- a/shared/backlog.c +++ /dev/null @@ -1,47 +0,0 @@ -#include - -#include "backlog.h" - -ws_s_backlog_database* g_ws_backlog_database = NULL; - -void ws_backlog_alloc(uint16_t record_amt) { - g_ws_backlog_database = malloc(sizeof(ws_s_backlog_database) + sizeof(ws_s_backlog_record) * record_amt); - g_ws_backlog_database->buffer_size = record_amt; - g_ws_backlog_database->buffer_start = 0; - g_ws_backlog_database->buffer_end = 0; -} - -void ws_backlog_add_record(ws_s_backlog_record record) { - static uint16_t id = 0; - - g_ws_backlog_database->records[g_ws_backlog_database->buffer_end].id = id++; - g_ws_backlog_database->records[g_ws_backlog_database->buffer_end].sens_atm_pressure = record.sens_atm_pressure; - g_ws_backlog_database->records[g_ws_backlog_database->buffer_end].sens_humidity = record.sens_humidity; - g_ws_backlog_database->records[g_ws_backlog_database->buffer_end].sens_temperature = record.sens_temperature; - - // shift buffer start/end - g_ws_backlog_database->buffer_end = (g_ws_backlog_database->buffer_end + 1) % g_ws_backlog_database->buffer_size; - if (g_ws_backlog_database->buffer_end == g_ws_backlog_database->buffer_start) - g_ws_backlog_database->buffer_start = (g_ws_backlog_database->buffer_start + 1) % g_ws_backlog_database->buffer_size; -} - -ws_s_backlog_record* ws_backlog_get_record(uint16_t record_index) { - return &g_ws_backlog_database->records[record_index]; -} - -ws_s_backlog_record* ws_backlog_get_last_record(uint16_t record_offset) { - return ws_backlog_get_record((g_ws_backlog_database->buffer_end - record_offset - 1) % g_ws_backlog_database->buffer_size); -} - -static uint16_t mod(uint16_t a, uint16_t b) { - uint16_t m = a % b; - return m < 0 ? (b < 0) ? m - b : m + b : m; -} - -uint16_t ws_backlog_get_record_count() { - // add buffer_size to the result of the modulo operation if it's result is negative - // (only works when buffer_size is less than 2^15) - // this is a consequence of the way in which c handles negative numbers in modulo operations - int16_t mod = (g_ws_backlog_database->buffer_end - g_ws_backlog_database->buffer_start) % g_ws_backlog_database->buffer_size; - return mod < 0 ? mod + g_ws_backlog_database->buffer_size : mod; -} diff --git a/shared/backlog.h b/shared/backlog.h deleted file mode 100644 index c8ea019..0000000 --- a/shared/backlog.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include - -/** - * @brief allocate backlog buffer and set global backlog pointer - * @param record_amt amount of records to keep before overwriting oldest record - */ -void ws_backlog_alloc(uint16_t record_amt); - -// enable struct packing -#pragma pack(push, 1) - -/** @brief backlog record */ -typedef struct { - uint16_t id; /**< unique record identifier, numbered sequentially */ - uint8_t sens_temperature; /**< temperature reading */ - uint8_t sens_humidity; /**< humidity reading */ - uint8_t sens_atm_pressure; /**< atmospheric pressure reading */ -} ws_s_backlog_record; - -typedef struct { - uint16_t buffer_size; /**< buffer size (amount of records) */ - uint16_t buffer_start; /** first record index */ - uint16_t buffer_end; /** last record index */ - ws_s_backlog_record records[]; /** record array */ -} ws_s_backlog_database; - -// disable struct packing -#pragma pack(pop) - -/** @brief global record backlog database pointer */ -extern ws_s_backlog_database* g_ws_backlog_database; - -/** - * @brief add record to database - * - * automatically sets record.id, pushes buffer_end forwards and overwrites the - * last record if the buffer is full - */ -void ws_backlog_add_record(ws_s_backlog_record record); - -/** - * there's intentionally no function to retrieve multiple records as an array, - * as this would either require - * (a) copying the selection which is not possible with the current memory - * constraints, or - * (b) giving a direct pointer, but this would cause undefined behavior at the - * ring buffer seam - */ - -/** @brief get pointer to record with index `record_index` from the database */ -ws_s_backlog_record* ws_backlog_get_record(uint16_t record_index); - -/** @brief get pointer to last record with offset `record_offset` from the database */ -ws_s_backlog_record* ws_backlog_get_last_record(uint16_t record_offset); - -/** @brief return amount of valid records in database */ -uint16_t ws_backlog_get_record_count(); diff --git a/shared/makefile b/shared/makefile deleted file mode 100644 index 2093f00..0000000 --- a/shared/makefile +++ /dev/null @@ -1,24 +0,0 @@ -CC = gcc -LD = gcc -RM = rm -f -CFLAGS = -g -std=c11 -LFLAGS = -TARGET = main - -SRCS := $(wildcard *.c) -OBJS := $(patsubst %.c,%.o, $(SRCS)) - -all: main - -%.o: %.c - $(CC) -c $(CFLAGS) $< -o $@ - -$(TARGET): $(OBJS) - $(LD) $^ $(LFLAGS) -o $@ - -clean: - $(RM) $(TARGET) $(OBJS) - -compile_commands: clean - compiledb make - diff --git a/shared/protocol.c b/shared/protocol.c index 55e6759..c6e5ddd 100644 --- a/shared/protocol.c +++ b/shared/protocol.c @@ -15,30 +15,30 @@ static ws_e_protocol_cmd ws_protocol_get_req_cmd_code(ws_s_protocol_parsed_req_c } void ws_protocol_parse_req_byte(ws_s_protocol_req_parser_state* state, char input) { - switch(input) { - case WS_PROTOCOL_C_EOL: { - break; - } + switch(input) { + case WS_PROTOCOL_C_EOL: { + break; + } - case WS_PROTOCOL_C_SPACE: { - if (!state->valid) return; + case WS_PROTOCOL_C_SPACE: { + if (!state->valid) return; state->arg_len++; - return; - } - - case WS_PROTOCOL_C_NULL: { - state->valid = false; - return; - } - - default: { - if (!state->valid) return; - state->cmd[state->cmd_len++] = input; - state->args_len[state->arg_len] += 1; - if (state->cmd_len == WS_PROTOCOL_CMD_BUFFER_LEN) state->valid = false; - return; - } - } + return; + } + + case WS_PROTOCOL_C_NULL: { + state->valid = false; + return; + } + + default: { + if (!state->valid) return; + state->cmd[state->cmd_len++] = input; + state->args_len[state->arg_len] += 1; + if (state->cmd_len == WS_PROTOCOL_CMD_BUFFER_LEN) state->valid = false; + return; + } + } // arg_len is used as an index while parsing, so add 1 to get length state->arg_len++; @@ -85,22 +85,23 @@ ws_protocol_parse_exit: } void ws_protocol_parse_req_bytes(ws_s_protocol_req_parser_state* state, char* input, unsigned int length) { - for (unsigned int i = 0; i < length; i++) ws_protocol_parse_req_byte(state, input[i]); + for (unsigned int i = 0; i < length; i++) ws_protocol_parse_req_byte(state, input[i]); } ws_s_protocol_req_parser_state* ws_protocol_req_parser_alloc() { - ws_s_protocol_req_parser_state* parser_state = malloc(sizeof(ws_s_protocol_req_parser_state) + sizeof(uint16_t) * WS_PROTOCOL_CMD_MAX_ARGUMENTS); - parser_state->cmd = malloc(sizeof(char) * WS_PROTOCOL_CMD_BUFFER_LEN); + ws_s_protocol_req_parser_state* parser_state = malloc(sizeof(ws_s_protocol_req_parser_state) + sizeof(uint16_t) * WS_PROTOCOL_CMD_MAX_ARGUMENTS); + parser_state->cmd = malloc(sizeof(char) * WS_PROTOCOL_CMD_BUFFER_LEN); + parser_state->target = NULL; ws_protocol_req_parser_reset(parser_state); - return parser_state; + return parser_state; } void ws_protocol_req_cmd_init(ws_s_protocol_req_parser_state* state) { - state->target = malloc(sizeof(ws_s_protocol_parsed_req_cmd) + sizeof(char*) * state->arg_len); - for (unsigned int i = 0; i < state->arg_len; i++) - state->target->argv[i] = malloc(sizeof(char) * (state->args_len[i] + 1)); + state->target = malloc(sizeof(ws_s_protocol_parsed_req_cmd) + sizeof(char*) * state->arg_len); + for (unsigned int i = 0; i < state->arg_len; i++) + state->target->argv[i] = malloc(sizeof(char) * (state->args_len[i] + 1)); - state->target->argc = state->arg_len; + state->target->argc = state->arg_len; unsigned int head = 0; for (unsigned int i = 0; i < state->arg_len; i++) { @@ -111,26 +112,26 @@ void ws_protocol_req_cmd_init(ws_s_protocol_req_parser_state* state) { } void ws_protocol_req_parser_free(ws_s_protocol_req_parser_state* state) { - if (state == NULL) return; - if (state->target != NULL) ws_protocol_req_cmd_free(state->target); + if (state == NULL) return; + if (state->target != NULL) ws_protocol_req_cmd_free(state->target); state->target = NULL; - free(state->cmd); - free(state); - return; + free(state->cmd); + free(state); + return; } void ws_protocol_req_parser_reset(ws_s_protocol_req_parser_state* state) { if (state->target != NULL) ws_protocol_req_cmd_free(state->target); - state->target = NULL; - state->valid = true; - state->cmd_len = 0; - state->arg_len = 0; + state->target = NULL; + state->valid = true; + state->cmd_len = 0; + state->arg_len = 0; memset(state->args_len, 0, sizeof(uint16_t) * WS_PROTOCOL_CMD_MAX_ARGUMENTS); } void ws_protocol_req_cmd_free(ws_s_protocol_parsed_req_cmd* cmd) { - for (unsigned int i = 0; i < cmd->argc; i++) - free(cmd->argv[i]); - free(cmd); - return; + for (int i = 0; i < cmd->argc; i++) + free(cmd->argv[i]); + free(cmd); + return; } diff --git a/shared/protocol.md b/shared/protocol.md index bafec4d..b6e955c 100644 --- a/shared/protocol.md +++ b/shared/protocol.md @@ -29,8 +29,9 @@ conventions. Returns the last `n` records in csv format. The first line has the csv table header, with the fields `id`, `temperature`, `humidity`, and `atmospheric_pressure`. The rest of the response consists of 1 record per line. -When `n` is 0, or no records exist yet, the csv header is still returned, but -without any records. +The amount of records is limited to the amount of valid records in the backlog +buffer. When the amount of returned records is 0, the response consists of the +csv header, but without any following records. ## Example transaction @@ -39,7 +40,7 @@ starting with `<`, and response by lines starting with `>`. ``` < last-records 5<0a> -> ok,115<0a> +> ok,73<0a> > id,temperature,humidity,atmospheric_pressure<0a> > 10dc,2f,c5,7f<0a> > 10dd,30,c6,7f<0a> diff --git a/shared/shared.mk b/shared/shared.mk new file mode 100644 index 0000000..f9586ff --- /dev/null +++ b/shared/shared.mk @@ -0,0 +1 @@ +OBJS += $(patsubst %.c,%-stm.o, $(wildcard ../shared/*.c)) diff --git a/shared/test.c b/shared/test.c deleted file mode 100644 index 287332a..0000000 --- a/shared/test.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "protocol.h" -#include "backlog.h" -#include "util.h" - -void ws_protocol_res_last_records(ws_s_protocol_parsed_req_cmd* parsed_cmd, ws_s_protocol_res* response, bool send) { - static unsigned int record_amount = 0; - const char* response_header = "id,temperature,humidity,atmospheric_pressure\n"; - const size_t response_line_size = sizeof("xxxx,xx,xx,xx\n"); - - if (!send) { - response->success = WS_PROTOCOL_CMD_RETURN_OK; - if (sscanf(parsed_cmd->argv[1], "%u", &record_amount) < 1) response->success = WS_PROTOCOL_CMD_RETURN_ERROR; - record_amount = WS_MIN(record_amount, ws_backlog_get_record_count()); - response->csh = true; - response->msg = ws_bin_s_alloc(0); - response->msg->bytes = strlen(response_header) + response_line_size * record_amount; - } else { - // example send routine - ws_protocol_send_data(response_header, strlen(response_header)); - char line[response_line_size + 1]; // +1 for null terminator -> sprintf - for (unsigned int i = 0; i < record_amount; i++) { - ws_s_backlog_record* record = ws_backlog_get_last_record(i); - sprintf(line, "%04x,%02x,%02x,%02x\n", record->id, record->sens_temperature, record->sens_humidity, record->sens_atm_pressure); - ws_protocol_send_data(line, response_line_size); - } - } -} - -void ws_protocol_send_data(const char* data, unsigned int length) { - printf("%.*s", length, data); -} - -int main() { - ws_backlog_alloc(10); - - // disable echo and enable raw mode - fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); - struct termios term; - tcgetattr(STDIN_FILENO, &term); - term.c_lflag &= ~(ECHO | ICANON); - term.c_cc[VTIME] = 0; - term.c_cc[VMIN] = 1; - tcsetattr(STDIN_FILENO, 0, &term); - - ws_s_protocol_req_parser_state* parser1 = ws_protocol_req_parser_alloc(); - - ws_backlog_add_record((ws_s_backlog_record) { - .sens_temperature = 0x29, - .sens_humidity = 0x34, - .sens_atm_pressure = 0x69, - }); - - ws_backlog_add_record((ws_s_backlog_record) { - .sens_temperature = 0x00, - .sens_humidity = 0x00, - .sens_atm_pressure = 0x00, - }); - - ws_backlog_add_record((ws_s_backlog_record) { - .sens_temperature = 0x01, - .sens_humidity = 0x01, - .sens_atm_pressure = 0x01, - }); - - fflush(stdout); - - char byte; - while(read(STDIN_FILENO, &byte, 1) > 0) - ws_protocol_parse_req_byte(parser1, byte); - - ws_protocol_req_parser_free(parser1); - parser1 = NULL; - - return 0; -} diff --git a/shared/testcmd b/shared/testcmd deleted file mode 100644 index 17f8842..0000000 --- a/shared/testcmd +++ /dev/null @@ -1 +0,0 @@ -last-records 5 diff --git a/stm32f091/backlog.c b/stm32f091/backlog.c index 926ccad..662fc75 100644 --- a/stm32f091/backlog.c +++ b/stm32f091/backlog.c @@ -33,11 +33,6 @@ ws_s_backlog_record* ws_backlog_get_last_record(uint16_t record_offset) { return ws_backlog_get_record((g_ws_backlog_database->buffer_end - record_offset - 1) % g_ws_backlog_database->buffer_size); } -static uint16_t mod(uint16_t a, uint16_t b) { - uint16_t m = a % b; - return m < 0 ? (b < 0) ? m - b : m + b : m; -} - uint16_t ws_backlog_get_record_count() { // add buffer_size to the result of the modulo operation if it's result is negative // (only works when buffer_size is less than 2^15) diff --git a/stm32f091/esp8266.c b/stm32f091/esp8266.c index 6f12191..4c5d0d2 100644 --- a/stm32f091/esp8266.c +++ b/stm32f091/esp8266.c @@ -22,7 +22,7 @@ void ws_esp8266_ATsendCommand(uint8_t* data){ } int ws_esp8266_checkOK(uint8_t *receiveData,int length){ char *ret=""; - char *ret1=""; + // char *ret1=""; HAL_UART_Transmit(&huart2, receiveData,length,1000); ret = strstr((char*)receiveData,"OK"); // ret = strstr((char*)receiveData,"change"); @@ -159,8 +159,9 @@ void ws_esp8266_serveraan(){ HAL_Delay(1000); } void ws_esp8266_serveruit(){ - int ret; - uint8_t buffer1[27]={0}; uint8_t Tx_server[]="AT+CIPSERVER=0\r\n"; + //int ret; + //uint8_t buffer1[27]={0}; + uint8_t Tx_server[]="AT+CIPSERVER=0\r\n"; // // while(ret!=1){ diff --git a/stm32f091/main.c b/stm32f091/main.c index 9235f1b..7cb0718 100644 --- a/stm32f091/main.c +++ b/stm32f091/main.c @@ -16,7 +16,6 @@ int main() { }); ws_backlog_alloc(24 * 60); - ws_sensor_read(); xTaskCreate(ws_sensor_read_task, "sensor", 128, NULL, 1, NULL); vTaskStartScheduler(); diff --git a/stm32f091/makefile b/stm32f091/makefile index 5a185de..20424c3 100644 --- a/stm32f091/makefile +++ b/stm32f091/makefile @@ -5,6 +5,8 @@ RM = rm -f TARGET = main +include ../shared/shared.mk + SHARED_FLAGS += -g SHARED_FLAGS += -DSTM32F091xC SHARED_FLAGS += -Wall @@ -74,9 +76,15 @@ $(TARGET).bin: $(TARGET).elf %.o: %.s $(CC) -c $(AFLAGS) $< -o $@ +lib/%.o: lib/%.c + $(CC) -c $(CFLAGS) -w $< -o $@ + %.o: %.c $(CC) -c $(CFLAGS) $< -o $@ +%-stm.o: %.c + $(CC) -c $(CFLAGS) $< -o $@ + $(TARGET).elf: $(OBJS) $(LD) $(LFLAGS) $^ -o $@ diff --git a/stm32f091/protocol.c b/stm32f091/protocol.c new file mode 100644 index 0000000..589ee5d --- /dev/null +++ b/stm32f091/protocol.c @@ -0,0 +1,33 @@ +#include + +#include "../shared/protocol.h" +#include "backlog.h" +#include "util.h" + +void ws_protocol_res_last_records(ws_s_protocol_parsed_req_cmd* parsed_cmd, ws_s_protocol_res* response, bool send) { + static unsigned int record_amount = 0; + const char* response_header = "id,temperature,humidity,atmospheric_pressure\n"; + const size_t response_line_size = sizeof("xxxx,xx,xx,xx\n"); + + if (!send) { + response->success = WS_PROTOCOL_CMD_RETURN_OK; + if (sscanf(parsed_cmd->argv[1], "%u", &record_amount) < 1) response->success = WS_PROTOCOL_CMD_RETURN_ERROR; + record_amount = WS_MIN(record_amount, ws_backlog_get_record_count()); + response->csh = true; + response->msg = ws_bin_s_alloc(0); + response->msg->bytes = strlen(response_header) + response_line_size * record_amount; + } else { + ws_protocol_send_data(response_header, strlen(response_header)); + char line[response_line_size + 1]; // +1 for null terminator -> sprintf + for (unsigned int i = 0; i < record_amount; i++) { + ws_s_backlog_record* record = ws_backlog_get_last_record(i); + sprintf(line, "%04x,%02x,%02x,%02x\n", record->id, record->sens_temperature, record->sens_humidity, record->sens_atm_pressure); + ws_protocol_send_data(line, response_line_size); + } + } +} + +void ws_protocol_send_data(const char* data, unsigned int length) { + //TODO: implement on esp data channels + HAL_UART_Transmit(&huart2, (uint8_t*) data, length, HAL_MAX_DELAY); +} diff --git a/stm32f091/sensor.c b/stm32f091/sensor.c index bc3cfd3..1c94e2a 100644 --- a/stm32f091/sensor.c +++ b/stm32f091/sensor.c @@ -58,6 +58,12 @@ void ws_sensor_read() { .sens_humidity = ws_sensor_humidity() }; ws_backlog_add_record(record); + + // < DEBUG PROTOCOL PARSING CODE > + // ws_s_protocol_req_parser_state* parser = ws_protocol_req_parser_alloc(); + // const char* request = "last-records 5\n"; + // ws_protocol_parse_req_bytes(parser, (char*) request, strlen(request)); + // ws_protocol_req_parser_free(parser); } void ws_sensor_read_task() { diff --git a/stm32f091/server.c b/stm32f091/server.c index e289245..4840527 100644 --- a/stm32f091/server.c +++ b/stm32f091/server.c @@ -28,7 +28,7 @@ void ws_server_demo() { uint8_t receive[24]={0}; uint8_t sendToQTData[]="gelukt"; uint8_t test[]="test"; - int ret; + //int ret; //ATsendCommand(sendToQTData); while (1) { diff --git a/stm32f091/util.h b/stm32f091/util.h index 8e3258f..92f093f 100644 --- a/stm32f091/util.h +++ b/stm32f091/util.h @@ -6,10 +6,11 @@ #include #include "setup.h" +#include "../shared/util.h" #define ws_usb_printf(fmt, ...) { \ char temp[255]; \ - sprintf(temp, fmt, ##__VA_ARGS__); \ + snprintf(temp, 255, fmt, ##__VA_ARGS__); \ HAL_UART_Transmit(&huart2, (uint8_t*) temp, sizeof(char) * strlen(temp), HAL_MAX_DELAY); \ } -- cgit v1.2.3 From babb6dc29a5c4af60292ffad5216317d13e2a685 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Fri, 28 Oct 2022 14:31:56 +0200 Subject: fix off-by-one error and create macro for switching serial debug print color --- shared/protocol.c | 2 +- stm32f091/consts.h | 2 +- stm32f091/esp8266.c | 3 +-- stm32f091/protocol.c | 14 ++++++++------ stm32f091/server.c | 8 +++----- stm32f091/setup.c | 7 +++++++ stm32f091/util.h | 4 ++++ 7 files changed, 25 insertions(+), 15 deletions(-) (limited to 'stm32f091/util.h') diff --git a/shared/protocol.c b/shared/protocol.c index e17a728..8887070 100644 --- a/shared/protocol.c +++ b/shared/protocol.c @@ -142,6 +142,6 @@ unsigned short ws_protocol_get_header_size(ws_s_protocol_res* response) { unsigned short size = 2; // comma and trailing newline if (response->success == WS_PROTOCOL_CMD_RETURN_OK) size += 2; // ok if (response->success == WS_PROTOCOL_CMD_RETURN_ERROR) size += 5; // error - size += ws_log16(response->msg->bytes); // amount of characters for message size (hex) + size += ws_log16(response->msg->bytes) + 1; // amount of characters for message size (hex) return size; } \ No newline at end of file diff --git a/stm32f091/consts.h b/stm32f091/consts.h index 955ceea..3d2ef5a 100644 --- a/stm32f091/consts.h +++ b/stm32f091/consts.h @@ -6,7 +6,7 @@ #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 754b45b..b896567 100644 --- a/stm32f091/esp8266.c +++ b/stm32f091/esp8266.c @@ -58,8 +58,7 @@ void ws_esp8266_send(uint8_t* data, size_t 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); + ws_dbg_set_usart2_tty_color(2); HAL_UART_Transmit(&huart2, g_ws_esp8266_dma_tx_buffer, strlen((char*) g_ws_esp8266_dma_tx_buffer), 100); #endif diff --git a/stm32f091/protocol.c b/stm32f091/protocol.c index 21e6527..4d605fc 100644 --- a/stm32f091/protocol.c +++ b/stm32f091/protocol.c @@ -9,27 +9,29 @@ void ws_protocol_res_last_records(ws_s_protocol_parsed_req_cmd* parsed_cmd, ws_s_protocol_res* response, bool send) { static unsigned int record_amount = 0; const char* response_header = "id,temperature,humidity,atmospheric_pressure\n"; - const size_t response_line_size = sizeof("xxxx,xx,xx,xx\n"); + const unsigned int response_line_len = strlen("xxxx,xx,xx,xx\n"); if (!send) { response->success = WS_PROTOCOL_CMD_RETURN_OK; response->csh = true; response->msg = ws_bin_s_alloc(0); response->msg->bytes = 0; - record_amount = WS_MIN(record_amount, ws_backlog_get_record_count()); if (sscanf(parsed_cmd->argv[1], "%u", &record_amount) < 1) response->success = WS_PROTOCOL_CMD_RETURN_ERROR; - else response->msg->bytes = strlen(response_header) + response_line_size * record_amount; + else { + record_amount = WS_MIN(record_amount, ws_backlog_get_record_count()); + response->msg->bytes = strlen(response_header) + response_line_len * record_amount; + } ws_server_req_respond_start(0, response->msg->bytes + ws_protocol_get_header_size(response)); } else { if (response->success == WS_PROTOCOL_CMD_RETURN_ERROR) return; ws_protocol_send_data(response_header, strlen(response_header)); - char line[response_line_size]; + char line[response_line_len + 1]; // + 1 for string terminator for (unsigned int i = 0; i < record_amount; i++) { ws_s_backlog_record* record = ws_backlog_get_last_record(i); sprintf(line, "%04x,%02x,%02x,%02x\n", record->id, record->sens_temperature, record->sens_humidity, record->sens_atm_pressure); - ws_protocol_send_data(line, response_line_size - 1); // remove string terminator + ws_protocol_send_data(line, response_line_len); // remove string terminator } - ws_protocol_send_data("\r\n", 2); // test + // ws_protocol_send_data("\r\n", 2); // test } } diff --git a/stm32f091/server.c b/stm32f091/server.c index 1419da8..6225eae 100644 --- a/stm32f091/server.c +++ b/stm32f091/server.c @@ -8,6 +8,7 @@ #include "server.h" #include "setup.h" #include "consts.h" +#include "util.h" ws_s_server_parser g_ws_server_parser = { .last_response = WS_SERVER_RC_NONE, @@ -48,8 +49,7 @@ void ws_server_req_finish(unsigned int channel, bool ignore) { #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) { #ifdef WS_DBG_PRINT_ESP_OVER_USART2 - uint8_t red[] = { 0x1b, 0x5b, 0x33, 0x31, 0x6d }; - HAL_UART_Transmit(&huart2, red, sizeof(red), 100); + ws_dbg_set_usart2_tty_color(1); HAL_UART_Transmit(&huart2, data, size, 100); #endif @@ -128,7 +128,6 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { case WS_SERVER_LM_CIPSEND_LISTENING: { if (next_few_bytes_are("SEND OK") || next_few_bytes_are("ERROR")) { ws_server_req_respond_end(0); - // g_ws_server_parser.mode = WS_SERVER_LM_IDLE; } break; } @@ -153,8 +152,7 @@ void ws_server_buffer_send_append(uint8_t* data, size_t size) { // TODO: refactor this void ws_server_buffer_send_finish() { #ifdef WS_DBG_PRINT_ESP_OVER_USART2 - uint8_t green[] = { 0x1b, 0x5b, 0x33, 0x32, 0x6d }; - HAL_UART_Transmit(&huart2, green, sizeof(green), 100); + ws_dbg_set_usart2_tty_color(2); HAL_UART_Transmit(&huart2, g_ws_esp8266_dma_tx_buffer, g_ws_esp8266_dma_tx_buffer_size, 100); #endif diff --git a/stm32f091/setup.c b/stm32f091/setup.c index 3bf331f..1591649 100644 --- a/stm32f091/setup.c +++ b/stm32f091/setup.c @@ -9,6 +9,7 @@ #include "setup.h" #include "backlog.h" #include "server.h" +#include "util.h" I2C_HandleTypeDef hi2c1 = { .Instance = I2C1, @@ -95,6 +96,12 @@ void ws_io_setup() { ws_backlog_alloc(24 * 60); // ws_backlog_alloc(10); +#ifdef WS_DBG_PRINT_ESP_OVER_USART2 + ws_dbg_set_usart2_tty_color(7); + const char restart_str[] = "\r\n--- stm restart ---\r\n"; + HAL_UART_Transmit(&huart2, restart_str, strlen(restart_str), 100); +#endif + #ifdef WS_ESP8266_WLAN_MAC ws_esp8266_set_mac(); #endif diff --git a/stm32f091/util.h b/stm32f091/util.h index 92f093f..9f5c1ec 100644 --- a/stm32f091/util.h +++ b/stm32f091/util.h @@ -14,3 +14,7 @@ HAL_UART_Transmit(&huart2, (uint8_t*) temp, sizeof(char) * strlen(temp), HAL_MAX_DELAY); \ } +#define ws_dbg_set_usart2_tty_color(color) { \ + uint8_t sgr[] = { 0x1b, 0x5b, 0x33, 0x30 + color, 0x6d }; \ + HAL_UART_Transmit(&huart2, sgr, sizeof(sgr), 100); \ +} -- cgit v1.2.3 From 7b4dbb553a4d22e88bafc38163d1b2f951c40fde Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sat, 29 Oct 2022 12:26:46 +0200 Subject: add bunch of unneccesary debug stuff, fix some stuff and expect espressif esp firmware --- stm32f091/esp8266.c | 2 +- stm32f091/server.c | 92 ++++++++++++++++++++++++++++++++--------------------- stm32f091/setup.c | 6 ++-- stm32f091/util.h | 31 +++++++++++++++++- 4 files changed, 89 insertions(+), 42 deletions(-) (limited to 'stm32f091/util.h') diff --git a/stm32f091/esp8266.c b/stm32f091/esp8266.c index b896567..159b55d 100644 --- a/stm32f091/esp8266.c +++ b/stm32f091/esp8266.c @@ -58,7 +58,7 @@ void ws_esp8266_send(uint8_t* data, size_t size) { g_ws_esp8266_dma_tx_buffer[limited_size] = 0x00; #ifdef WS_DBG_PRINT_ESP_OVER_USART2 - ws_dbg_set_usart2_tty_color(2); + ws_dbg_set_usart2_tty_color(WS_DBG_TTY_COLOR_TX); HAL_UART_Transmit(&huart2, g_ws_esp8266_dma_tx_buffer, strlen((char*) g_ws_esp8266_dma_tx_buffer), 100); #endif diff --git a/stm32f091/server.c b/stm32f091/server.c index 46d18f0..e0c97dc 100644 --- a/stm32f091/server.c +++ b/stm32f091/server.c @@ -49,7 +49,7 @@ void ws_server_req_finish(unsigned int channel, bool ignore) { #define next_few_bytes_are(code) (((i + sizeof(code) - 2) < size) && (strncmp((char*)&data[i], code, sizeof(code) - 1) == 0)) void ws_server_req_incoming(uint8_t* data, size_t size) { #ifdef WS_DBG_PRINT_ESP_OVER_USART2 - ws_dbg_set_usart2_tty_color(1); + ws_dbg_set_usart2_tty_color(WS_DBG_TTY_COLOR_RX); HAL_UART_Transmit(&huart2, data, size, 100); #endif @@ -64,12 +64,19 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { case WS_SERVER_LM_STATUS_CODE: { bool code_got = false; if (next_few_bytes_are("OK")) { + i += 1; code_got = true; g_ws_server_parser.last_response = WS_SERVER_RC_OK; - } else if (next_few_bytes_are("ERROR") || next_few_bytes_are("FAIL")) { + } else if (next_few_bytes_are("ERROR")) { + i += 4; + code_got = true; + g_ws_server_parser.last_response = WS_SERVER_RC_ERR; + } else if (next_few_bytes_are("FAIL")) { + i += 3; code_got = true; g_ws_server_parser.last_response = WS_SERVER_RC_ERR; } else if (next_few_bytes_are("busy p...")) { + i += 8; code_got = true; g_ws_server_parser.last_response = WS_SERVER_RC_BUSY; } @@ -80,49 +87,49 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { if (next_few_bytes_are("+IPD,")) { i += 4; // skip I, P, D, and comma g_ws_server_parser.mode = WS_SERVER_LM_IPD_LISTENING; - } else if (next_few_bytes_are("> ")) { + } else if (next_few_bytes_are(">")) { // ">" on official espressif firmware, "> " on ai-thinker firmware g_ws_server_parser.mode = WS_SERVER_LM_CIPSEND_LISTENING; ws_server_buffer_send_finish(); } break; } case WS_SERVER_LM_IPD_LISTENING: { - switch (g_ws_server_parser.channel_listen_mode) { - case WS_SERVER_CL_CHANNEL_ID: { - if (byte == ',') { - g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_DATA_LENGTH; - break; - } - g_ws_server_parser.current_channel *= 10; - g_ws_server_parser.current_channel += byte - '0'; // ascii to int + switch (g_ws_server_parser.channel_listen_mode) { + case WS_SERVER_CL_CHANNEL_ID: { + if (byte == ',') { + g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_DATA_LENGTH; break; } - case WS_SERVER_CL_DATA_LENGTH: { - if (byte == ':') { - g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_DATA_READ; - if (g_ws_server_parser.channel_data_length > WS_PROTOCOL_CMD_BUFFER_LEN) - g_ws_server_parser.channel_data_ignore = true; - break; - } - g_ws_server_parser.channel_data_length *= 10; - g_ws_server_parser.channel_data_length += byte - '0'; // ascii to int + g_ws_server_parser.current_channel *= 10; + g_ws_server_parser.current_channel += byte - '0'; // ascii to int + break; + } + case WS_SERVER_CL_DATA_LENGTH: { + if (byte == ':') { + g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_DATA_READ; + if (g_ws_server_parser.channel_data_length > WS_PROTOCOL_CMD_BUFFER_LEN) + g_ws_server_parser.channel_data_ignore = true; break; } - case WS_SERVER_CL_DATA_READ: { - ws_server_req_parse_byte(g_ws_server_parser.current_channel, byte, g_ws_server_parser.channel_data_ignore); - g_ws_server_parser.channel_data_counter++; - if (g_ws_server_parser.channel_data_counter == g_ws_server_parser.channel_data_length) { - g_ws_server_parser.current_channel = 0; - g_ws_server_parser.channel_data_counter = 0; - g_ws_server_parser.channel_data_length = 0; - g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_CHANNEL_ID; - ws_server_req_finish(g_ws_server_parser.current_channel, g_ws_server_parser.channel_data_ignore); - g_ws_server_parser.mode = WS_SERVER_LM_IDLE; - } - break; + g_ws_server_parser.channel_data_length *= 10; + g_ws_server_parser.channel_data_length += byte - '0'; // ascii to int + break; + } + case WS_SERVER_CL_DATA_READ: { + ws_server_req_parse_byte(g_ws_server_parser.current_channel, byte, g_ws_server_parser.channel_data_ignore); + g_ws_server_parser.channel_data_counter++; + if (g_ws_server_parser.channel_data_counter == g_ws_server_parser.channel_data_length) { + g_ws_server_parser.current_channel = 0; + g_ws_server_parser.channel_data_counter = 0; + g_ws_server_parser.channel_data_length = 0; + g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_CHANNEL_ID; + ws_server_req_finish(g_ws_server_parser.current_channel, g_ws_server_parser.channel_data_ignore); + g_ws_server_parser.mode = WS_SERVER_LM_IDLE; } - default: {} + break; } + default: {} + } break; } case WS_SERVER_LM_CIPSEND_LISTENING: { @@ -151,15 +158,26 @@ void ws_server_buffer_send_append(uint8_t* data, size_t size) { // TODO: refactor this void ws_server_buffer_send_finish() { + /* const int chunk_size = 16; // esp is garbage + + for (unsigned int chunk = 0; chunk <= (g_ws_esp8266_dma_tx_buffer_size / chunk_size); chunk++) { + HAL_UART_Transmit_DMA(&huart1, &g_ws_esp8266_dma_tx_buffer[chunk_size * chunk], WS_MIN(chunk_size, g_ws_esp8266_dma_tx_buffer_size % chunk_size)); + __HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE); + while (!__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TC2)); + } */ #ifdef WS_DBG_PRINT_ESP_OVER_USART2 - ws_dbg_set_usart2_tty_color(2); + ws_dbg_set_usart2_tty_color(WS_DBG_TTY_COLOR_TX); HAL_UART_Transmit(&huart2, g_ws_esp8266_dma_tx_buffer, g_ws_esp8266_dma_tx_buffer_size, 100); #endif - HAL_UART_Transmit_DMA(&huart1, g_ws_esp8266_dma_tx_buffer, g_ws_esp8266_dma_tx_buffer_size); - __HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE); + HAL_UART_Transmit(&huart1, g_ws_esp8266_dma_tx_buffer, g_ws_esp8266_dma_tx_buffer_size, 100); + // for (unsigned j = 0; j < 10000; j++) asm("nop"); // esp garbage + // for (unsigned int i = 0; i < g_ws_esp8266_dma_tx_buffer_size; i++) { + // // send as slow as possible because the esp is garbage + // for (unsigned j = 0; j < 1000; j++) asm("nop"); // did i mention the esp is garbage + // HAL_UART_Transmit(&huart1, &g_ws_esp8266_dma_tx_buffer[i], 1, 100); + // } g_ws_esp8266_dma_tx_buffer_size = 0; - while (!__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TC2)); } // TODO: refactor this diff --git a/stm32f091/setup.c b/stm32f091/setup.c index 1591649..ef00a29 100644 --- a/stm32f091/setup.c +++ b/stm32f091/setup.c @@ -97,18 +97,18 @@ void ws_io_setup() { // ws_backlog_alloc(10); #ifdef WS_DBG_PRINT_ESP_OVER_USART2 - ws_dbg_set_usart2_tty_color(7); + ws_dbg_set_usart2_tty_color(WS_DBG_TTY_COLOR_DBGMSG); const char restart_str[] = "\r\n--- stm restart ---\r\n"; - HAL_UART_Transmit(&huart2, restart_str, strlen(restart_str), 100); + HAL_UART_Transmit(&huart2, (uint8_t*) restart_str, strlen(restart_str), 100); #endif + ws_esp8266_ap_client_mode(); #ifdef WS_ESP8266_WLAN_MAC ws_esp8266_set_mac(); #endif #ifdef WS_ESP8266_WLAN_IP ws_esp8266_set_ip(); #endif - ws_esp8266_ap_client_mode(); do ws_esp8266_connect(); while (g_ws_server_parser.last_response == WS_SERVER_RC_ERR); ws_esp8266_start_tcp_server(); } diff --git a/stm32f091/util.h b/stm32f091/util.h index 9f5c1ec..dde3677 100644 --- a/stm32f091/util.h +++ b/stm32f091/util.h @@ -8,6 +8,35 @@ #include "setup.h" #include "../shared/util.h" +#define WS_DBG_TTY_COLOR_BLK 0x0 +#define WS_DBG_TTY_COLOR_RED 0x1 +#define WS_DBG_TTY_COLOR_GRN 0x2 +#define WS_DBG_TTY_COLOR_YLW 0x3 +#define WS_DBG_TTY_COLOR_BLU 0x4 +#define WS_DBG_TTY_COLOR_VLT 0x5 +#define WS_DBG_TTY_COLOR_CYN 0x6 +#define WS_DBG_TTY_COLOR_WHI 0x7 +#define WS_DBG_TTY_COLOR_BR_BLK 0x8 +#define WS_DBG_TTY_COLOR_BR_RED 0x9 +#define WS_DBG_TTY_COLOR_BR_GRN 0xa +#define WS_DBG_TTY_COLOR_BR_YLW 0xb +#define WS_DBG_TTY_COLOR_BR_BLU 0xc +#define WS_DBG_TTY_COLOR_BR_VLT 0xd +#define WS_DBG_TTY_COLOR_BR_CYN 0xe +#define WS_DBG_TTY_COLOR_BR_WHI 0xf + +// serial debug color scheme +#define WS_DBG_TTY_COLOR_DBGMSG WS_DBG_TTY_COLOR_BR_BLK +#define WS_DBG_TTY_COLOR_TX WS_DBG_TTY_COLOR_GRN +#define WS_DBG_TTY_COLOR_RX WS_DBG_TTY_COLOR_RED + +// unused +// #define WS_DBG_TTY_COLOR_CMD_ECHO WS_DBG_TTY_COLOR_BLK +// #define WS_DBG_TTY_COLOR_STATUS_CODE WS_DBG_TTY_COLOR_YLW +// #define WS_DBG_TTY_COLOR_IDLE WS_DBG_TTY_COLOR_VLT +// #define WS_DBG_TTY_COLOR_IPD_LISTENING WS_DBG_TTY_COLOR_GRN +// #define WS_DBG_TTY_COLOR_CIPSEND_LISTENING WS_DBG_TTY_COLOR_RED + #define ws_usb_printf(fmt, ...) { \ char temp[255]; \ snprintf(temp, 255, fmt, ##__VA_ARGS__); \ @@ -15,6 +44,6 @@ } #define ws_dbg_set_usart2_tty_color(color) { \ - uint8_t sgr[] = { 0x1b, 0x5b, 0x33, 0x30 + color, 0x6d }; \ + uint8_t sgr[] = { 0x1b, 0x5b, 0x33 + (color > 7 ? 6 : 0), 0x30 + (color & 0b111), 0x6d }; \ HAL_UART_Transmit(&huart2, sgr, sizeof(sgr), 100); \ } -- cgit v1.2.3 From 9947b4aa803b0430e38be3bd6f7179b45b201213 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sat, 29 Oct 2022 17:15:56 +0200 Subject: send data in chunks for reliability --- stm32f091/esp8266.c | 6 +-- stm32f091/protocol.c | 4 +- stm32f091/server.c | 108 +++++++++++++++++++++++++++++++-------------------- stm32f091/server.h | 24 +++++++++--- stm32f091/todo.md | 2 +- stm32f091/util.h | 2 + 6 files changed, 92 insertions(+), 54 deletions(-) (limited to 'stm32f091/util.h') diff --git a/stm32f091/esp8266.c b/stm32f091/esp8266.c index 159b55d..74ec347 100644 --- a/stm32f091/esp8266.c +++ b/stm32f091/esp8266.c @@ -75,9 +75,9 @@ void ws_esp8266_ap_client_mode() { } void ws_esp8266_start_tcp_server() { - ws_esp8266_send_seq("AT+CIPSERVER=0\r\n"); - ws_esp8266_send_seq("AT+CIPMUX=1\r\n"); - ws_esp8266_send_seq("AT+CIPSERVER=1," WS_SERVER_PORT "\r\n"); + ws_esp8266_send_seq("AT+CIPSERVER=0\r\n"); // stop tcp server (if running) + ws_esp8266_send_seq("AT+CIPMUX=1\r\n"); // enable multiplexing (allow multiple connections) + ws_esp8266_send_seq("AT+CIPSERVER=1," WS_SERVER_PORT "\r\n"); // start tcp server } void ws_esp8266_set_mac() { diff --git a/stm32f091/protocol.c b/stm32f091/protocol.c index 4d605fc..ca46b3b 100644 --- a/stm32f091/protocol.c +++ b/stm32f091/protocol.c @@ -21,7 +21,6 @@ void ws_protocol_res_last_records(ws_s_protocol_parsed_req_cmd* parsed_cmd, ws_s record_amount = WS_MIN(record_amount, ws_backlog_get_record_count()); response->msg->bytes = strlen(response_header) + response_line_len * record_amount; } - ws_server_req_respond_start(0, response->msg->bytes + ws_protocol_get_header_size(response)); } else { if (response->success == WS_PROTOCOL_CMD_RETURN_ERROR) return; ws_protocol_send_data(response_header, strlen(response_header)); @@ -29,9 +28,8 @@ void ws_protocol_res_last_records(ws_s_protocol_parsed_req_cmd* parsed_cmd, ws_s for (unsigned int i = 0; i < record_amount; i++) { ws_s_backlog_record* record = ws_backlog_get_last_record(i); sprintf(line, "%04x,%02x,%02x,%02x\n", record->id, record->sens_temperature, record->sens_humidity, record->sens_atm_pressure); - ws_protocol_send_data(line, response_line_len); // remove string terminator + ws_protocol_send_data(line, response_line_len); } - // ws_protocol_send_data("\r\n", 2); // test } } diff --git a/stm32f091/server.c b/stm32f091/server.c index cc47251..0e8cadf 100644 --- a/stm32f091/server.c +++ b/stm32f091/server.c @@ -18,10 +18,14 @@ ws_s_server_parser g_ws_server_parser = { .channel_data_length = 0, .channel_data_counter = 0, .channel_listen_mode = WS_SERVER_CL_CHANNEL_ID, + + .rc = { 0 }, }; static ws_s_protocol_req_parser_state* g_ws_protocol_parsers[WS_SERVER_MAX_CHANNELS] = {0}; -static unsigned int g_ws_esp8266_dma_tx_buffer_size = 0; +static unsigned int g_ws_esp8266_dma_tx_buffer_head = 0; +static unsigned int g_ws_esp8266_dma_tx_buffer_tail = 0; +static unsigned int g_ws_esp8266_dma_tx_buffer_cs = 0; // chunk size void ws_server_req_parse_byte(unsigned int channel, uint8_t byte, bool ignore) { if (ignore) return; @@ -44,6 +48,13 @@ void ws_server_req_finish(unsigned int channel, bool ignore) { } } +static bool ws_server_is_response(char data, uint8_t* counter, const char* cmd, unsigned short cmd_len) { + if (data == cmd[*counter]) *counter += 1; + else *counter = 0; + if (*counter == cmd_len) return true; + return false; +} + // 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) - 2) < size) && (strncmp((char*)&data[i], code, sizeof(code) - 1) == 0)) @@ -63,20 +74,16 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { } case WS_SERVER_LM_STATUS_CODE: { bool code_got = false; - if (next_few_bytes_are("OK")) { - i += 1; + if (ws_server_is_response(byte, &g_ws_server_parser.rc.s_ok, "OK", 2)) { code_got = true; g_ws_server_parser.last_response = WS_SERVER_RC_OK; - } else if (next_few_bytes_are("ERROR")) { - i += 4; + } else if (ws_server_is_response(byte, &g_ws_server_parser.rc.s_error, "ERROR", 5)) { code_got = true; g_ws_server_parser.last_response = WS_SERVER_RC_ERR; - } else if (next_few_bytes_are("FAIL")) { - i += 3; + } else if (ws_server_is_response(byte, &g_ws_server_parser.rc.s_fail, "FAIL", 4)) { code_got = true; g_ws_server_parser.last_response = WS_SERVER_RC_ERR; - } else if (next_few_bytes_are("busy p...")) { - i += 8; + } else if (ws_server_is_response(byte, &g_ws_server_parser.rc.s_busy, "busy p...", 9)) { code_got = true; g_ws_server_parser.last_response = WS_SERVER_RC_BUSY; } @@ -84,12 +91,12 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { break; } case WS_SERVER_LM_IDLE: { - if (next_few_bytes_are("+IPD,")) { - i += 4; // skip I, P, D, and comma + if (ws_server_is_response(byte, &g_ws_server_parser.rc.i_ipd, "+IPD,", 5)) { g_ws_server_parser.mode = WS_SERVER_LM_IPD_LISTENING; - } else if (next_few_bytes_are(">")) { // ">" on official espressif firmware, "> " on ai-thinker firmware + } else if (ws_server_is_response(byte, &g_ws_server_parser.rc.i_prompt, ">", 1)) { + // ^^^ this is ">" on official espressif firmware, "> " on ai-thinker firmware g_ws_server_parser.mode = WS_SERVER_LM_CIPSEND_LISTENING; - ws_server_buffer_send_finish(); + ws_server_buffer_send_chunk(); } break; } @@ -125,6 +132,7 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { g_ws_server_parser.channel_listen_mode = WS_SERVER_CL_CHANNEL_ID; ws_server_req_finish(g_ws_server_parser.current_channel, g_ws_server_parser.channel_data_ignore); g_ws_server_parser.mode = WS_SERVER_LM_IDLE; + ws_server_buffer_request_chunk_send(); } break; } @@ -133,8 +141,8 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { break; } case WS_SERVER_LM_CIPSEND_LISTENING: { - if (next_few_bytes_are("SEND OK") || next_few_bytes_are("ERROR")) { - ws_server_req_respond_end(0); + if (ws_server_is_response(byte, &g_ws_server_parser.rc.l_send_ok, "SEND OK", 7) || ws_server_is_response(byte, &g_ws_server_parser.rc.l_error, "ERROR", 5)) { + ws_server_buffer_request_chunk_send(); } break; } @@ -143,6 +151,13 @@ void ws_server_req_incoming(uint8_t* data, size_t size) { } } +/** @brief get amount of bytes in g_ws_esp8266_dma_tx_buffer until \n */ +static unsigned int ws_server_next_line_length() { + for (unsigned int i = g_ws_esp8266_dma_tx_buffer_tail; i <= g_ws_esp8266_dma_tx_buffer_head; i++) + if (g_ws_esp8266_dma_tx_buffer[i] == '\n') return i - g_ws_esp8266_dma_tx_buffer_tail + 1; + return g_ws_esp8266_dma_tx_buffer_head - g_ws_esp8266_dma_tx_buffer_tail; +} + 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); @@ -152,43 +167,52 @@ void ws_server_send(uint8_t* data, size_t size) { void ws_server_buffer_send_append(uint8_t* data, size_t size) { // TODO: buffer overrun protection // while (!__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TC2)); // make sure buffer isn't used - strncpy((char*) &g_ws_esp8266_dma_tx_buffer[g_ws_esp8266_dma_tx_buffer_size], (char*) data, size); // append string - g_ws_esp8266_dma_tx_buffer_size += size; // shift head + strncpy((char*) &g_ws_esp8266_dma_tx_buffer[g_ws_esp8266_dma_tx_buffer_head], (char*) data, size); // append string + g_ws_esp8266_dma_tx_buffer_head += size; // shift head } -// TODO: refactor this -void ws_server_buffer_send_finish() { - /* const int chunk_size = 16; // esp is garbage - - for (unsigned int chunk = 0; chunk <= (g_ws_esp8266_dma_tx_buffer_size / chunk_size); chunk++) { - HAL_UART_Transmit_DMA(&huart1, &g_ws_esp8266_dma_tx_buffer[chunk_size * chunk], WS_MIN(chunk_size, g_ws_esp8266_dma_tx_buffer_size % chunk_size)); - __HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE); - while (!__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TC2)); - } */ +void ws_server_buffer_request_chunk_send() { + g_ws_esp8266_dma_tx_buffer_cs = ws_server_next_line_length(); + + char* cmd = NULL; + size_t len; + + if (g_ws_esp8266_dma_tx_buffer_cs > 0) { + len = asiprintf(&cmd, "AT+CIPSEND=%d,%d\r\n", g_ws_server_parser.current_channel, g_ws_esp8266_dma_tx_buffer_cs); + } else { + len = asiprintf(&cmd, "AT+CIPCLOSE=%d\r\n", g_ws_server_parser.current_channel); + } + + g_ws_server_parser.mode = WS_SERVER_LM_CMD_ECHO; + #ifdef WS_DBG_PRINT_ESP_OVER_USART2 ws_dbg_set_usart2_tty_color(WS_DBG_TTY_COLOR_TX); + HAL_UART_Transmit(&huart2, (uint8_t*) cmd, len, 100); #endif + HAL_UART_Transmit(&huart1, (uint8_t*) cmd, len, 100); +} - // HAL_UART_Transmit(&huart1, g_ws_esp8266_dma_tx_buffer, g_ws_esp8266_dma_tx_buffer_size, 100); - for (unsigned j = 0; j < 1000000; j++) asm("nop"); // esp garbage - for (unsigned int i = 0; i < g_ws_esp8266_dma_tx_buffer_size; i++) { - // send as slow as possible because the esp is garbage - for (unsigned j = 0; j < 10000; j++) asm("nop"); // did i mention the esp is garbage - HAL_UART_Transmit(&huart1, &g_ws_esp8266_dma_tx_buffer[i], 1, 100); +void ws_server_buffer_send_chunk() { #ifdef WS_DBG_PRINT_ESP_OVER_USART2 - HAL_UART_Transmit(&huart2, &g_ws_esp8266_dma_tx_buffer[i], 1, 100); + ws_dbg_set_usart2_tty_color(WS_DBG_TTY_COLOR_TX); + HAL_UART_Transmit(&huart2, &g_ws_esp8266_dma_tx_buffer[g_ws_esp8266_dma_tx_buffer_tail], g_ws_esp8266_dma_tx_buffer_cs, 100); #endif + HAL_UART_Transmit(&huart1, &g_ws_esp8266_dma_tx_buffer[g_ws_esp8266_dma_tx_buffer_tail], g_ws_esp8266_dma_tx_buffer_cs, 100); + g_ws_esp8266_dma_tx_buffer_tail += g_ws_esp8266_dma_tx_buffer_cs; + + if (g_ws_esp8266_dma_tx_buffer_head == g_ws_esp8266_dma_tx_buffer_tail) { + g_ws_esp8266_dma_tx_buffer_head = g_ws_esp8266_dma_tx_buffer_tail = 0; } - g_ws_esp8266_dma_tx_buffer_size = 0; -} -// TODO: refactor this -void ws_server_req_respond_start(unsigned int channel, size_t size) { - char* cmd = NULL; - size_t len = asiprintf(&cmd, "AT+CIPSEND=%d,%d\r\n", channel, size); - g_ws_server_parser.mode = WS_SERVER_LM_CMD_ECHO; - ws_esp8266_send((uint8_t*) cmd, len); - while (!__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TC2)); +// #ifdef WS_DBG_PRINT_ESP_OVER_USART2 +// ws_dbg_set_usart2_tty_color(WS_DBG_TTY_COLOR_TX); +// HAL_UART_Transmit(&huart2, g_ws_esp8266_dma_tx_buffer, g_ws_esp8266_dma_tx_buffer_head, 100); +// #endif +// +// HAL_UART_Transmit(&huart1, g_ws_esp8266_dma_tx_buffer, g_ws_esp8266_dma_tx_buffer_head, 100); +// g_ws_esp8266_dma_tx_buffer_head = 0; +// +// HAL_UART_Transmit(&huart1, (uint8_t*) "+++", 3, 100); } // TODO: refactor this diff --git a/stm32f091/server.h b/stm32f091/server.h index 128b579..07c49d9 100644 --- a/stm32f091/server.h +++ b/stm32f091/server.h @@ -25,6 +25,17 @@ typedef enum { WS_SERVER_RC_OK, } ws_e_server_response_code; +typedef struct { + uint8_t s_ok; /** @brief status code OK */ + uint8_t s_error; /** @brief status code OK */ + uint8_t s_fail; /** @brief status code OK */ + uint8_t s_busy; /** @brief status code OK */ + uint8_t i_ipd; /** @brief idle +IPD, */ + uint8_t i_prompt; /** @brief idle > */ + uint8_t l_send_ok; /** @brief ipd listen SEND OK */ + uint8_t l_error; /** @brief ipd listen ERROR */ +} ws_s_server_parser_response_counter; + typedef struct { ws_e_server_listen_mode mode; ws_e_server_response_code last_response; @@ -33,6 +44,7 @@ typedef struct { unsigned int channel_data_counter; ws_e_channel_listen_mode channel_listen_mode; bool channel_data_ignore; + ws_s_server_parser_response_counter rc; } ws_s_server_parser; /** @brief global server parser struct */ @@ -50,10 +62,10 @@ extern ws_s_server_parser g_ws_server_parser; */ void ws_server_req_incoming(uint8_t* data, size_t size); -/** @brief send AT response header for incoming request on specific channel */ -void ws_server_req_respond_start(unsigned int channel, size_t size); -/** @brief send AT tcp close on specific channel */ -void ws_server_req_respond_end(unsigned int channel); +// /** @brief send AT response header for incoming request on specific channel */ +// void ws_server_req_respond_start(unsigned int channel); +// /** @brief send AT tcp close on specific channel */ +// void ws_server_req_respond_end(unsigned int channel); /** @brief send data to esp, waiting until server returns to idle mode */ void ws_server_send(uint8_t* data, size_t size); @@ -82,4 +94,6 @@ void ws_server_req_parse_byte(unsigned int channel, uint8_t byte, bool ignore); void ws_server_req_finish(unsigned int channel, bool ignore); void ws_server_buffer_send_append(uint8_t* data, size_t size); -void ws_server_buffer_send_finish(); + +void ws_server_buffer_request_chunk_send(); +void ws_server_buffer_send_chunk(); diff --git a/stm32f091/todo.md b/stm32f091/todo.md index 77c37e6..1d42bf8 100644 --- a/stm32f091/todo.md +++ b/stm32f091/todo.md @@ -2,7 +2,7 @@ - [ ] more documentation in header files (for both client and stm code) - [ ] design/architecture document -- [ ] more tests in the test document +- [x] more tests in the test document - [ ] handle errors from `AT+CIPSEND`, these look like this: ``` > AT0,CONNECT diff --git a/stm32f091/util.h b/stm32f091/util.h index dde3677..11bee6f 100644 --- a/stm32f091/util.h +++ b/stm32f091/util.h @@ -30,6 +30,8 @@ #define WS_DBG_TTY_COLOR_TX WS_DBG_TTY_COLOR_GRN #define WS_DBG_TTY_COLOR_RX WS_DBG_TTY_COLOR_RED +#define debugger asm("nop") + // unused // #define WS_DBG_TTY_COLOR_CMD_ECHO WS_DBG_TTY_COLOR_BLK // #define WS_DBG_TTY_COLOR_STATUS_CODE WS_DBG_TTY_COLOR_YLW -- cgit v1.2.3