diff options
| -rw-r--r-- | shared/protocol.c | 14 | ||||
| -rw-r--r-- | shared/protocol.h | 3 | ||||
| -rw-r--r-- | shared/util.c | 7 | ||||
| -rw-r--r-- | shared/util.h | 2 | ||||
| -rw-r--r-- | stm32f091/esp8266.c | 27 | ||||
| -rw-r--r-- | stm32f091/protocol.c | 8 | ||||
| -rw-r--r-- | stm32f091/server.c | 54 | ||||
| -rw-r--r-- | stm32f091/server.h | 13 | ||||
| -rw-r--r-- | stm32f091/setup.c | 3 | 
9 files changed, 88 insertions, 43 deletions
diff --git a/shared/protocol.c b/shared/protocol.c index ca0edc4..fcc84a4 100644 --- a/shared/protocol.c +++ b/shared/protocol.c @@ -3,6 +3,7 @@  #include <string.h>  #include "protocol.h" +#include "util.h"  #define WS_CMD_MAP(parsed_cmd, name, code) \  	if (strlen(parsed_cmd->argv[0]) == strlen(name) && strncmp(parsed_cmd->argv[0], name, strlen(name)) == 0) return code; @@ -99,10 +100,7 @@ ws_s_protocol_req_parser_state* ws_protocol_req_parser_alloc() {  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)); // segfaults on 2nd run? -	// state->target->argv stays empty according to debugger -	// goes to HardFault_Handler on 2nd iteration -	// this might be the stm running out of heap memory though i'm not sure +		state->target->argv[i] = malloc(sizeof(char) * (state->args_len[i] + 1));  	state->target->argc = state->arg_len; @@ -138,3 +136,11 @@ void ws_protocol_req_cmd_free(ws_s_protocol_parsed_req_cmd* cmd) {  	free(cmd);  	return;  } + +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) +	return size; +}
\ No newline at end of file diff --git a/shared/protocol.h b/shared/protocol.h index fbe29d6..5bcb114 100644 --- a/shared/protocol.h +++ b/shared/protocol.h @@ -5,7 +5,7 @@  #include "bin.h" -#define WS_PROTOCOL_CMD_MAX_ARGUMENTS (1) +#define WS_PROTOCOL_CMD_MAX_ARGUMENTS (2)  #define WS_PROTOCOL_CMD_BUFFER_LEN (40)  #define WS_PROTOCOL_CMD_AMOUNT (1) @@ -148,3 +148,4 @@ static ws_protocol_res_handler_t* g_ws_protocol_res_handlers[WS_PROTOCOL_CMD_AMO  	[WS_PROTOCOL_CMD_LAST_RECORDS] = &ws_protocol_res_last_records,  }; +unsigned short ws_protocol_get_header_size(ws_s_protocol_res* response);
\ No newline at end of file diff --git a/shared/util.c b/shared/util.c new file mode 100644 index 0000000..ea972b0 --- /dev/null +++ b/shared/util.c @@ -0,0 +1,7 @@ +#include "util.h" + +unsigned int ws_log16(unsigned int x) { +    unsigned int l = 0; +    while (x >>= 4) ++l; // bitshift right by 4 until x == 0 +    return l; +}
\ No newline at end of file diff --git a/shared/util.h b/shared/util.h index f39ff34..94a3dfe 100644 --- a/shared/util.h +++ b/shared/util.h @@ -2,3 +2,5 @@  #define WS_MIN(a, b) (((a) < (b)) ? (a) : (b))  #define WS_MAX(a, b) (((a) > (b)) ? (a) : (b)) + +unsigned int ws_log16(unsigned int x); diff --git a/stm32f091/esp8266.c b/stm32f091/esp8266.c index d45954e..db134a0 100644 --- a/stm32f091/esp8266.c +++ b/stm32f091/esp8266.c @@ -80,30 +80,3 @@ void ws_esp8266_set_mac() {  void ws_esp8266_set_ip() {  	ws_esp8266_send_seq("AT+CIPSTA=\"" WS_ESP8266_WLAN_IP "\"\r\n");  } - -// TODO: refactor code from here to EOF -void ws_esp8266_ATsendCommand(uint8_t* data){ -	char dataChar[20]; -	uint8_t Tx_send[]="AT+CIPSEND=0,"; - -	itoa(strlen((char*)data),dataChar,10); -	strcat((char*)Tx_send,dataChar); -	strcat((char*)Tx_send,"\r\n"); -	HAL_UART_Transmit(&huart1, Tx_send, strlen((char*)Tx_send),1000); -	HAL_Delay(2000); -	HAL_UART_Transmit(&huart1, data, strlen((char*)data),1000); -	HAL_Delay(1000); -	HAL_UART_Transmit(&huart2, data, strlen((char*)data),1000); -	HAL_Delay(5000); -} -void ws_esp8266_close(){ - -	uint8_t Tx_close[]="AT+CIPCLOSE=0\r\n"; - - -	    HAL_UART_Transmit(&huart1, Tx_close,strlen((char*)Tx_close), 100); - -		HAL_Delay(3000); - -} - diff --git a/stm32f091/protocol.c b/stm32f091/protocol.c index 589ee5d..3a8d78b 100644 --- a/stm32f091/protocol.c +++ b/stm32f091/protocol.c @@ -3,6 +3,8 @@  #include "../shared/protocol.h"  #include "backlog.h"  #include "util.h" +#include "server.h" +#include "esp8266.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; @@ -16,6 +18,7 @@ void ws_protocol_res_last_records(ws_s_protocol_parsed_req_cmd* parsed_cmd, ws_s  		response->csh = true;  		response->msg = ws_bin_s_alloc(0);  		response->msg->bytes = strlen(response_header) + response_line_size * record_amount; +		ws_server_req_respond_start(0, response->msg->bytes + ws_protocol_get_header_size(response));  	} else {  		ws_protocol_send_data(response_header, strlen(response_header));  		char line[response_line_size + 1]; // +1 for null terminator -> sprintf @@ -24,10 +27,11 @@ void ws_protocol_res_last_records(ws_s_protocol_parsed_req_cmd* parsed_cmd, ws_s  			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);  		} +		ws_protocol_send_data("\r\n", 2); // test  	}  }  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); +	ws_server_buffer_send_append((uint8_t*) data, length); +	// HAL_UART_Transmit(&huart1, (uint8_t*) data, length, HAL_MAX_DELAY);  } diff --git a/stm32f091/server.c b/stm32f091/server.c index 7e44774..d4f7e20 100644 --- a/stm32f091/server.c +++ b/stm32f091/server.c @@ -9,7 +9,7 @@  #include "setup.h"  #include "consts.h" -static ws_s_server_parser g_ws_server_parser = { +ws_s_server_parser g_ws_server_parser = {  	.last_response = WS_SERVER_RC_NONE,  	.mode = WS_SERVER_LM_IDLE, @@ -20,7 +20,7 @@ static ws_s_server_parser g_ws_server_parser = {  };  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_index = 0;  void ws_server_req_parse_byte(unsigned int channel, uint8_t byte, bool ignore) {  	if (ignore) return; @@ -80,6 +80,9 @@ 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 (byte == '>') { +					g_ws_server_parser.mode = WS_SERVER_LM_CIPSEND_LISTENING; +					ws_server_buffer_send_finish();  				}  				break;  			} @@ -114,6 +117,7 @@ void ws_server_req_incoming(uint8_t* data, size_t size) {  								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;  						} @@ -121,6 +125,14 @@ 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")) { +					i += 6; +					// g_ws_server_parser.mode = WS_SERVER_LM_IDLE; +					ws_server_req_respond_end(0); +				} +				break; +			}  			default: {}  		}  	} @@ -132,9 +144,39 @@ void ws_server_send(uint8_t* data, size_t 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_send[]="AT+CIPSEND=0,LEN:"; -	uint8_t Tx_close[]="AT+CIPCLOSE=0\r\n"; -	return; +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_index], (char*) data, size); // append string +	g_ws_esp8266_dma_tx_buffer_index += size; // shift head +} + +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); +	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); +	g_ws_esp8266_dma_tx_buffer_index = 0; +	while (!__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TC2)); +} + +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)); +} + +void ws_server_req_respond_end(unsigned int channel) { +	char* cmd = NULL; +	size_t len = asiprintf(&cmd, "AT+CIPCLOSE=%d\r\n", channel); +	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));  } diff --git a/stm32f091/server.h b/stm32f091/server.h index 44882e4..128b579 100644 --- a/stm32f091/server.h +++ b/stm32f091/server.h @@ -9,6 +9,7 @@ typedef enum {  	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_SERVER_LM_CIPSEND_LISTENING, /** @brief AT+CIPSEND sent, now reading data */  } ws_e_server_listen_mode;  typedef enum { @@ -34,6 +35,9 @@ typedef struct {  	bool channel_data_ignore;  } ws_s_server_parser; +/** @brief global server parser struct */ +extern ws_s_server_parser g_ws_server_parser; +  /**   * @brief +IPD incoming request handler   * @@ -46,8 +50,10 @@ typedef struct {   */  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 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 data to esp, waiting until server returns to idle mode */  void ws_server_send(uint8_t* data, size_t size); @@ -74,3 +80,6 @@ void ws_server_req_parse_byte(unsigned int channel, uint8_t byte, bool ignore);   * @param ignore  ignore mode   */  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(); diff --git a/stm32f091/setup.c b/stm32f091/setup.c index 5b6c6a4..1971809 100644 --- a/stm32f091/setup.c +++ b/stm32f091/setup.c @@ -8,6 +8,7 @@  #include "esp8266.h"  #include "setup.h"  #include "backlog.h" +#include "server.h"  I2C_HandleTypeDef hi2c1 = {  	.Instance = I2C1, @@ -101,7 +102,7 @@ void ws_io_setup() {  	ws_esp8266_set_ip();  #endif  	ws_esp8266_ap_client_mode(); -	ws_esp8266_connect(); +	do ws_esp8266_connect(); while (g_ws_server_parser.last_response == WS_SERVER_RC_ERR);  	ws_esp8266_start_tcp_server();  }  |