diff options
Diffstat (limited to 'stm32f091')
-rw-r--r-- | stm32f091/backlog.c | 36 | ||||
-rw-r--r-- | stm32f091/backlog.h | 4 | ||||
-rw-r--r-- | stm32f091/consts.h | 27 | ||||
-rw-r--r-- | stm32f091/esp8266.c | 240 | ||||
-rw-r--r-- | stm32f091/esp8266.h | 44 | ||||
-rw-r--r-- | stm32f091/main.c | 12 | ||||
-rw-r--r-- | stm32f091/makefile | 17 | ||||
-rw-r--r-- | stm32f091/protocol.c | 41 | ||||
-rw-r--r-- | stm32f091/readme.md | 11 | ||||
-rw-r--r-- | stm32f091/sensor.c | 6 | ||||
-rw-r--r-- | stm32f091/server.c | 255 | ||||
-rw-r--r-- | stm32f091/server.h | 99 | ||||
-rw-r--r-- | stm32f091/setup.c | 97 | ||||
-rw-r--r-- | stm32f091/setup.h | 17 | ||||
-rw-r--r-- | stm32f091/util.h | 51 | ||||
-rw-r--r-- | stm32f091/wifi.def.h | 7 |
16 files changed, 673 insertions, 291 deletions
diff --git a/stm32f091/backlog.c b/stm32f091/backlog.c index 3f21924..662fc75 100644 --- a/stm32f091/backlog.c +++ b/stm32f091/backlog.c @@ -2,33 +2,41 @@ #include "backlog.h" -ws_s_backlog_database* WS_G_BACKLOG_DATABASE = NULL; +ws_s_backlog_database* g_ws_backlog_database = NULL; void ws_backlog_alloc(uint16_t record_amt) { - WS_G_BACKLOG_DATABASE = malloc(sizeof(ws_s_backlog_database) + sizeof(ws_s_backlog_record) * record_amt); - WS_G_BACKLOG_DATABASE->buffer_size = record_amt; - WS_G_BACKLOG_DATABASE->buffer_start = 0; - WS_G_BACKLOG_DATABASE->buffer_end = 0; + 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; - WS_G_BACKLOG_DATABASE->records[WS_G_BACKLOG_DATABASE->buffer_end].id = id++; - WS_G_BACKLOG_DATABASE->records[WS_G_BACKLOG_DATABASE->buffer_end].sens_atm_pressure = record.sens_atm_pressure; - WS_G_BACKLOG_DATABASE->records[WS_G_BACKLOG_DATABASE->buffer_end].sens_humidity = record.sens_humidity; - WS_G_BACKLOG_DATABASE->records[WS_G_BACKLOG_DATABASE->buffer_end].sens_temperature = record.sens_temperature; + 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 - WS_G_BACKLOG_DATABASE->buffer_end = (WS_G_BACKLOG_DATABASE->buffer_end + 1) % WS_G_BACKLOG_DATABASE->buffer_size; - if (WS_G_BACKLOG_DATABASE->buffer_end == WS_G_BACKLOG_DATABASE->buffer_start) - WS_G_BACKLOG_DATABASE->buffer_start = (WS_G_BACKLOG_DATABASE->buffer_start + 1) % WS_G_BACKLOG_DATABASE->buffer_size; + 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 &WS_G_BACKLOG_DATABASE->records[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((WS_G_BACKLOG_DATABASE->buffer_end - record_offset - 1) % WS_G_BACKLOG_DATABASE->buffer_size); + return ws_backlog_get_record((g_ws_backlog_database->buffer_end - record_offset - 1) % g_ws_backlog_database->buffer_size); +} + +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/stm32f091/backlog.h b/stm32f091/backlog.h index 465b3c0..c8ea019 100644 --- a/stm32f091/backlog.h +++ b/stm32f091/backlog.h @@ -30,7 +30,7 @@ typedef struct { #pragma pack(pop) /** @brief global record backlog database pointer */ -extern ws_s_backlog_database* WS_G_BACKLOG_DATABASE; +extern ws_s_backlog_database* g_ws_backlog_database; /** * @brief add record to database @@ -55,3 +55,5 @@ 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/stm32f091/consts.h b/stm32f091/consts.h new file mode 100644 index 0000000..3d2ef5a --- /dev/null +++ b/stm32f091/consts.h @@ -0,0 +1,27 @@ +#pragma once + +#include "wifi.h" + +#define WS_SERVER_PORT "80" +#define WS_SERVER_MAX_CHANNELS 4 + +#define WS_DMA_RX_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 +#define WS_PINOUT_I2C_SCL_PIN GPIO_PIN_8 +#define WS_PINOUT_I2C_SCL_PORT GPIOB + +#define WS_PINOUT_USART1_RX_PIN GPIO_PIN_10 +#define WS_PINOUT_USART1_RX_PORT GPIOA +#define WS_PINOUT_USART1_TX_PIN GPIO_PIN_9 +#define WS_PINOUT_USART1_TX_PORT GPIOA + +#define WS_PINOUT_USART2_RX_PIN GPIO_PIN_3 +#define WS_PINOUT_USART2_RX_PORT GPIOA +#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 6f12191..74ec347 100644 --- a/stm32f091/esp8266.c +++ b/stm32f091/esp8266.c @@ -2,208 +2,88 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stm32f0xx.h> #include "esp8266.h" #include "setup.h" - -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); -} -int ws_esp8266_checkOK(uint8_t *receiveData,int length){ - char *ret=""; - char *ret1=""; - HAL_UART_Transmit(&huart2, receiveData,length,1000); - ret = strstr((char*)receiveData,"OK"); - // ret = strstr((char*)receiveData,"change"); - // memset(receiveData,0,30); - if((ret[0]='O') && (ret[1]=='K')){ - //HAL_UART_Transmit(&huart2, (uint8_t*)ret, sizeof(ret), 100); - return 1; - - } -// else if((ret1[0]='c') && (ret1[1]=='h')){ -// //HAL_UART_Transmit(&huart2, (uint8_t*)ret, sizeof(ret), 100); -// return 1; -// -// } - else{ - return 0; - } - +#include "consts.h" +#include "server.h" +#include "util.h" + +// macro for concise sending of multiple commands +#define ws_esp8266_send_seq(cmd) { \ + uint8_t _cmd[] = cmd; \ + ws_server_send(_cmd, sizeof(_cmd)); \ } -int ws_esp8266_receivingMsg(uint8_t *receiveData,int length){ - char *ret=""; - HAL_UART_Transmit(&huart2, receiveData,length,1000); - ret = strstr((char*)receiveData,"+IPD"); - // memset(receiveData,0,30); - if((ret[0]='+') && (ret[1]=='I')){ - //HAL_UART_Transmit(&huart2, (uint8_t*)ret, sizeof(ret), 100); - return 1; - } - else{ - return 0; - } +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]; -} -int ws_esp8266_unlink(uint8_t *receiveData,int length){ - char *ret=""; - HAL_UART_Transmit(&huart2, receiveData,length,1000); - ret = strstr((char*)receiveData,"UNLINK"); - // memset(receiveData,0,30); - if((ret[0]='U') && (ret[1]=='N')){ - //HAL_UART_Transmit(&huart2, (uint8_t*)ret, sizeof(ret), 100); - return 1; - - } - else{ - return 0; - } +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) { + if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) { + __HAL_UART_CLEAR_IDLEFLAG(&huart1); + // 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 ws_esp8266_StartEsp(){ - - uint8_t Tx_AT[]="AT\r\n"; - uint8_t Rx_buffer[10]={0}; - for(int i=0;i<3;i++){ - // HAL_UART_Transmit(&huart2, hier,sizeof(hier),100); - HAL_UART_Transmit_IT(&huart1, Tx_AT,strlen((char*)Tx_AT)); - HAL_UART_Receive_IT(&huart1, Rx_buffer, 10); - - - HAL_UART_Transmit(&huart2, Rx_buffer,10,100); - HAL_Delay(5000); - //memset(Rx_buffer,0,sizeof(Rx_buffer)); +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_disconnect(){ - int ret; - uint8_t Tx_disconnect[]="AT+CWQAP\r\n";uint8_t buffer[17]={0}; - while(ret!=1){ - - HAL_UART_Transmit_IT(&huart1, Tx_disconnect,strlen((char*)Tx_disconnect)); - HAL_UART_Receive_IT(&huart1, buffer, 17); - HAL_Delay(2000); - if(ws_esp8266_checkOK(buffer,17)==1){ - ret=1; - } +void ws_esp8266_send(uint8_t* data, size_t size) { + size_t limited_size = WS_MIN(size, WS_DMA_TX_BUFFER_SIZE - 1); + 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 + 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 - HAL_Delay(5000); + 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_mode(){ - int ret; - uint8_t buffer1[20]={0}; uint8_t Tx_mode[]="AT+CWMODE=1\r\n"; - - while(ret!=1){ - - HAL_UART_Transmit_IT(&huart1, Tx_mode,strlen((char*)Tx_mode)); - HAL_UART_Receive_IT(&huart1, buffer1, 20); - HAL_Delay(1000); - - if(ws_esp8266_checkOK(buffer1,20)==1){ - ret=1; - - } - } - - HAL_Delay(1000); +void ws_esp8266_connect() { + ws_esp8266_send_seq("AT+CWJAP=\"" WS_ESP8266_WLAN_SSID "\",\"" WS_ESP8266_WLAN_PASSWD "\"\r\n"); } -void ws_esp8266_connect(){ - uint8_t Tx_network[]="AT+CWJAP=\"Test\",\"12345678\"\r\n"; - - - HAL_UART_Transmit(&huart1, Tx_network,strlen((char*)Tx_network),1000); - HAL_Delay(10000); -// HAL_UART_Transmit(&huart1, Tx_network,sizeof(Tx_network),1000); -// HAL_Delay(10000); - - - - +void ws_esp8266_ap_client_mode() { + ws_esp8266_send_seq("AT+CWMODE=1\r\n"); } -void ws_esp8266_serveraan(){ - int ret; - uint8_t buffer1[30]={0}; uint8_t Tx_server[]="AT+CIPSERVER=1,80\r\n"; - - while(ret!=1){ - - HAL_UART_Transmit_IT(&huart1, Tx_server,strlen((char*)Tx_server)); - HAL_UART_Receive_IT(&huart1, buffer1, 30); - HAL_Delay(2000); - - if(ws_esp8266_checkOK(buffer1,30)==1){ - ret=1; - - } - } - - HAL_Delay(1000); +void ws_esp8266_start_tcp_server() { + 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_serveruit(){ - int ret; - uint8_t buffer1[27]={0}; uint8_t Tx_server[]="AT+CIPSERVER=0\r\n"; -// -// while(ret!=1){ - - HAL_UART_Transmit_IT(&huart1, Tx_server,strlen((char*)Tx_server)); -// HAL_UART_Receive_IT(&huart1, buffer1, 27); - HAL_Delay(3000); - -// if(unlink(buffer1,27)==1){ -// ret=1; -// -// } -// -// } - HAL_Delay(1000); +void ws_esp8266_set_mac() { + ws_esp8266_send_seq("AT+CIPSTAMAC=\"" WS_ESP8266_WLAN_MAC "\"\r\n"); } -void ws_esp8266_mux(){ - int ret; - uint8_t buffer2[20]={0}; uint8_t Tx_mux[]="AT+CIPMUX=1\r\n"; - - while(ret!=1){ - - HAL_UART_Transmit_IT(&huart1, Tx_mux,strlen((char*)Tx_mux)); - HAL_UART_Receive_IT(&huart1, buffer2, 20); - HAL_Delay(2000); - - if(ws_esp8266_checkOK(buffer2,20)==1){ - ret=1; - - } - - } - - HAL_Delay(5000); -} -void ws_esp8266_close(){ - - uint8_t Tx_close[]="AT+CIPCLOSE=0\r\n"; - - - HAL_UART_Transmit_IT(&huart1, Tx_close,strlen((char*)Tx_close)); - - HAL_Delay(3000); +void ws_esp8266_set_ip() { + ws_esp8266_send_seq("AT+CIPSTA=\"" WS_ESP8266_WLAN_IP "\"\r\n"); } - diff --git a/stm32f091/esp8266.h b/stm32f091/esp8266.h index c09a557..94a7356 100644 --- a/stm32f091/esp8266.h +++ b/stm32f091/esp8266.h @@ -1,16 +1,38 @@ #pragma once +#include <stm32f0xx_hal.h> +#include <stdlib.h> #include <stdint.h> +#include <stdbool.h> -void ws_esp8266_ATsendCommand(uint8_t* data); -int ws_esp8266_checkOK(uint8_t *receiveData,int length); -int ws_esp8266_receivingMsg(uint8_t *receiveData,int length); -int ws_esp8266_unlink(uint8_t *receiveData,int length); -void ws_esp8266_StartEsp(); -void ws_esp8266_disconnect(); -void ws_esp8266_mode(); +#include "consts.h" + +/** @brief DMA rx buffer */ +extern uint8_t g_ws_esp8266_dma_rx_buffer[WS_DMA_RX_BUFFER_SIZE]; +/** @brief null-terminated tx buffer string */ +extern uint8_t g_ws_esp8266_dma_tx_buffer[WS_DMA_TX_BUFFER_SIZE]; + +/** @brief DMA1 channel 2-3 & DMA2 channel 1-2 interrupt handler */ +void DMA1_Ch2_3_DMA2_Ch1_2_IRQHandler(void); +/** @brief DMA1 channel 1 interrupt handler */ +void DMA1_Ch1_IRQHandler(void); +/** @brief USART1 interrupt handler */ +void USART1_IRQHandler(void); + +/** @brief send data to esp over uart with dma */ +void ws_esp8266_send(uint8_t* data, size_t size); + +/** @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(); -void ws_esp8266_serveraan(); -void ws_esp8266_serveruit(); -void ws_esp8266_mux(); -void ws_esp8266_close(); +/** @brief set esp to access point client mode (connect to AP, not become one) */ +void ws_esp8266_ap_client_mode(); +/** @brief initialize and configure the tcp server */ +void ws_esp8266_start_tcp_server(); + +/** @brief set mac address of the esp client */ +void ws_esp8266_set_mac(); +/** @brief set static ip address of the esp client */ +void ws_esp8266_set_ip(); diff --git a/stm32f091/main.c b/stm32f091/main.c index 9235f1b..67c0a8d 100644 --- a/stm32f091/main.c +++ b/stm32f091/main.c @@ -5,19 +5,9 @@ #include "main.h" #include "setup.h" #include "sensor.h" -#include "backlog.h" int main() { ws_io_setup(); - HAL_GPIO_Init(GPIOA, &(GPIO_InitTypeDef) { - .Pin = GPIO_PIN_5, - .Mode = GPIO_MODE_OUTPUT_PP, - .Pull = GPIO_NOPULL - }); - - ws_backlog_alloc(24 * 60); - ws_sensor_read(); - - xTaskCreate(ws_sensor_read_task, "sensor", 128, NULL, 1, NULL); + xTaskCreate(ws_sensor_read_task, "sensor", 64, NULL, 1, NULL); vTaskStartScheduler(); } diff --git a/stm32f091/makefile b/stm32f091/makefile index 5a185de..dd03761 100644 --- a/stm32f091/makefile +++ b/stm32f091/makefile @@ -4,6 +4,9 @@ OC = arm-none-eabi-objcopy RM = rm -f TARGET = main +HOST=$(strip $(shell uname -o)) + +include ../shared/shared.mk SHARED_FLAGS += -g SHARED_FLAGS += -DSTM32F091xC @@ -11,7 +14,6 @@ SHARED_FLAGS += -Wall SHARED_FLAGS += -Wextra # SHARED_FLAGS += -Wno-register SHARED_FLAGS += -Wa,--defsym,CALL_ARM_SYSTEM_INIT=1 -# SHARED_FLAGS += -I/usr/arm-none-eabi/include/ SHARED_FLAGS += -I./lib/STM32-base-STM32Cube/HAL/STM32F0xx/inc SHARED_FLAGS += -I./lib/STM32-base-STM32Cube/HAL/STM32F0xx/inc/Legacy SHARED_FLAGS += -I./lib/STM32-base-STM32Cube/CMSIS/ARM/inc @@ -20,7 +22,10 @@ SHARED_FLAGS += -I./lib/STM32-base/startup SHARED_FLAGS += -I./lib/FreeRTOS-Kernel/include SHARED_FLAGS += -I./lib/FreeRTOS-Kernel/portable/GCC/ARM_CM0/ SHARED_FLAGS += -I. -SHARED_FLAGS += -O1 +ifeq ($(HOST),GNU/Linux) +SHARED_FLAGS += -I/usr/arm-none-eabi/include/ +endif +# SHARED_FLAGS += -O1 SHARED_FLAGS += -ffunction-sections SHARED_FLAGS += -fdata-sections SHARED_FLAGS += -Wl,--gc-sections @@ -74,14 +79,20 @@ $(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 $@ flash: $(TARGET).bin - st-flash write $(TARGET).bin 0x08000000 + st-flash --reset write $(TARGET).bin 0x08000000 compile_commands: clean compiledb make -n diff --git a/stm32f091/protocol.c b/stm32f091/protocol.c new file mode 100644 index 0000000..f4be08f --- /dev/null +++ b/stm32f091/protocol.c @@ -0,0 +1,41 @@ +#include <stdio.h> + +#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 int record_amount = 0; + static unsigned int record_offset = 0; + const char* response_header = "id,temperature,humidity,atmospheric_pressure\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; + if (sscanf(parsed_cmd->argv[1], "%x", &record_amount) < 1) response->success = WS_PROTOCOL_CMD_RETURN_ERROR; + if (sscanf(parsed_cmd->argv[2], "%x", &record_offset) < 1) response->success = WS_PROTOCOL_CMD_RETURN_ERROR; + else { + record_amount = WS_MIN(record_amount + record_offset, ws_backlog_get_record_count()); + record_amount = WS_MAX(0, record_amount - record_offset); + response->msg->bytes = strlen(response_header) + response_line_len * record_amount; + } + } else { + if (response->success == WS_PROTOCOL_CMD_RETURN_ERROR) return; + ws_protocol_send_data(response_header, strlen(response_header)); + 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 + record_offset); + 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); + } + } +} + +void ws_protocol_send_data(const char* data, unsigned int length) { + ws_server_buffer_send_append((uint8_t*) data, length); +} diff --git a/stm32f091/readme.md b/stm32f091/readme.md new file mode 100644 index 0000000..d2758b5 --- /dev/null +++ b/stm32f091/readme.md @@ -0,0 +1,11 @@ +# stm32 firmware subdirectory + +- uses make +- make sure to initialize the git submodules +- all warnings from source files in the lib/ subfolder are hidden +- copy wifi.def.h to wifi.h and edit the network credentials +- the initialization code is broken in some way which means that a soft reset + is required for the uart dma to work, either (a) press the reset button on + the development board after plugging in, or (b) run `st-flash reset` after + plugging in. + 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..d69ef1e 100644 --- a/stm32f091/server.c +++ b/stm32f091/server.c @@ -3,55 +3,222 @@ #include <stdlib.h> #include <string.h> -#include "setup.h" -#include "server.h" +#include "../shared/protocol.h" #include "esp8266.h" +#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, + .mode = WS_SERVER_LM_IDLE, + + .current_channel = 0, + .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_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; + if (channel >= WS_SERVER_MAX_CHANNELS) return; + + if (g_ws_protocol_parsers[channel] == NULL) { + g_ws_protocol_parsers[channel] = ws_protocol_req_parser_alloc(); + } -void ws_server_demo() { - uint8_t ok[]= "ok\r\n"; - uint8_t hier[]= "hier\r\n"; - //disconnect();//connect();// - - ws_esp8266_StartEsp(); - HAL_UART_Transmit(&huart2, hier,sizeof(hier),1000); - ws_esp8266_close(); - HAL_UART_Transmit(&huart2, hier,sizeof(hier),1000); - ws_esp8266_serveruit(); - HAL_UART_Transmit(&huart2, hier,sizeof(hier),1000); - ws_esp8266_mux(); - HAL_UART_Transmit(&huart2, hier,sizeof(hier),1000); - ws_esp8266_mode(); - HAL_UART_Transmit(&huart2, hier,sizeof(hier),1000); - - ws_esp8266_serveraan(); - HAL_UART_Transmit(&huart2, ok,sizeof(ok),1000); - uint8_t receive[24]={0}; - uint8_t sendToQTData[]="gelukt"; - uint8_t test[]="test"; - int ret; - //ATsendCommand(sendToQTData); - while (1) - { - - if(receive[0]=='\0') - { - HAL_UART_Receive_IT(&huart1, receive, 24); + ws_protocol_parse_req_byte(g_ws_protocol_parsers[channel], byte); +} + +void ws_server_req_finish(unsigned int channel, bool ignore) { + if (ignore) return; + if (channel >= WS_SERVER_MAX_CHANNELS) return; + + if (g_ws_protocol_parsers[channel] != NULL) { + ws_protocol_req_parser_free(g_ws_protocol_parsers[channel]); + g_ws_protocol_parsers[channel] = NULL; + } +} + +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; +} + +void ws_server_req_incoming(uint8_t* data, size_t size) { +#ifdef WS_DBG_PRINT_ESP_OVER_USART2 + ws_dbg_set_usart2_tty_color(WS_DBG_TTY_COLOR_RX); + 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 (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 (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 (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 (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; + } + if (code_got) g_ws_server_parser.mode = WS_SERVER_LM_IDLE; + break; } - else - { - HAL_UART_Transmit(&huart2, test,strlen((char*)test),1000); - HAL_Delay(5000); - - // if(receivingMsg(receive, 24)==1) - // { - // ret=1; - ws_esp8266_ATsendCommand(sendToQTData); - ws_esp8266_close(); - memset(receive,0,24); - //} + case WS_SERVER_LM_IDLE: { + 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 (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_chunk(); + } + 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 + 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 + 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; + ws_server_buffer_request_chunk_send(); + } + break; + } + default: {} + } + break; + } + case WS_SERVER_LM_CIPSEND_LISTENING: { + 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; + } + default: {} + } + } +} + +/** @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); + while (g_ws_server_parser.mode != WS_SERVER_LM_IDLE) {}; +} +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_head], (char*) data, size); // append string + g_ws_esp8266_dma_tx_buffer_head += size; // shift head +} - } +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); + } + free(cmd); + + 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); +} + +void ws_server_buffer_send_chunk() { +#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_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; + } + +// #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 +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)); + free(cmd); } diff --git a/stm32f091/server.h b/stm32f091/server.h index 6a3501d..07c49d9 100644 --- a/stm32f091/server.h +++ b/stm32f091/server.h @@ -1,6 +1,99 @@ #pragma once -void ws_server_demo(); +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> -/** FreeRTOS task that listens for incoming requests from the esp */ -void ws_server_listen_task(); +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_SERVER_LM_CIPSEND_LISTENING, /** @brief AT+CIPSEND sent, now reading data */ +} ws_e_server_listen_mode; + +typedef enum { + WS_SERVER_CL_CHANNEL_ID, /** @brief listen channel id */ + WS_SERVER_CL_DATA_LENGTH, /** @brief listen for data byte length */ + WS_SERVER_CL_DATA_READ, /** @brief listen for data and pipe to ws_protocol_parse_req_byte */ +} ws_e_channel_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 { + 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; + unsigned int current_channel; + unsigned int channel_data_length; + 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 */ +extern ws_s_server_parser g_ws_server_parser; + +/** + * @brief +IPD incoming request handler + * + * this function takes chunks of data from the esp8266 and parses +IPD + * commands. when a valid +IPD command is detected, it gets forwarded to + * ws_protocol_parse_req_byte. + * + * @param data pointer to data array + * @param size amount of bytes allowed to be read from `data` + */ +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); +// /** @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); + +/** + * @brief parse byte from channel + * + * automatically creates parser struct and passes data onto protocol parser + * functions + * + * @param channel request channel + * @param byte data byte + * @param ignore ignore mode + */ +void ws_server_req_parse_byte(unsigned int channel, uint8_t byte, bool ignore); + +/** + * @brief close connection + * + * deallocates any parser struct that were automatically created in + * ws_server_req_parse_byte + * + * @param channel request channel + * @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_request_chunk_send(); +void ws_server_buffer_send_chunk(); diff --git a/stm32f091/setup.c b/stm32f091/setup.c index fec2b7c..ef00a29 100644 --- a/stm32f091/setup.c +++ b/stm32f091/setup.c @@ -5,7 +5,11 @@ #include <FreeRTOS.h> #include <task.h> +#include "esp8266.h" #include "setup.h" +#include "backlog.h" +#include "server.h" +#include "util.h" I2C_HandleTypeDef hi2c1 = { .Instance = I2C1, @@ -20,16 +24,14 @@ I2C_HandleTypeDef hi2c1 = { }; UART_HandleTypeDef huart1 = { - .Instance = USART1, - .Init.BaudRate = 115200, - .Init.WordLength = UART_WORDLENGTH_8B, - .Init.StopBits = UART_STOPBITS_1, - .Init.Parity = UART_PARITY_NONE, - .Init.Mode = UART_MODE_TX_RX, - .Init.HwFlowCtl = UART_HWCONTROL_NONE, - .Init.OverSampling = UART_OVERSAMPLING_16, - .Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE, - .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT, + .Instance = USART1, + .Init.BaudRate = 115200, + .Init.WordLength = UART_WORDLENGTH_8B, + .Init.StopBits = UART_STOPBITS_1, + .Init.Parity = UART_PARITY_NONE, + .Init.Mode = UART_MODE_TX_RX, + .Init.HwFlowCtl = UART_HWCONTROL_NONE, + .Init.OverSampling = UART_OVERSAMPLING_16, }; UART_HandleTypeDef huart2 = { @@ -45,10 +47,33 @@ UART_HandleTypeDef huart2 = { .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT, }; +DMA_HandleTypeDef hdma_usart1_rx = { + .Instance = DMA1_Channel1, + .Init.Direction = DMA_PERIPH_TO_MEMORY, + .Init.PeriphInc = DMA_PINC_DISABLE, + .Init.MemInc = DMA_MINC_ENABLE, + .Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE, + .Init.MemDataAlignment = DMA_MDATAALIGN_BYTE, + .Init.Mode = DMA_CIRCULAR, + .Init.Priority = DMA_PRIORITY_LOW, +}; + +DMA_HandleTypeDef hdma_usart1_tx = { + .Instance = DMA1_Channel2, + .Init.Direction = DMA_MEMORY_TO_PERIPH, + .Init.PeriphInc = DMA_PINC_DISABLE, + .Init.MemInc = DMA_MINC_ENABLE, + .Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE, + .Init.MemDataAlignment = DMA_MDATAALIGN_BYTE, + .Init.Mode = DMA_NORMAL, + .Init.Priority = DMA_PRIORITY_LOW, +}; + static void ws_io_clock_setup(); static void ws_io_i2c_setup(); static void ws_io_usart1_setup(); static void ws_io_usart2_setup(); +static void ws_io_dma_setup(); static void ws_setup_error_handler(); void ws_io_setup() { @@ -56,8 +81,36 @@ void ws_io_setup() { ws_io_clock_setup(); ws_io_i2c_setup(); + ws_io_dma_setup(); ws_io_usart1_setup(); ws_io_usart2_setup(); + ws_io_dma_setup(); + + HAL_GPIO_Init(GPIOA, &(GPIO_InitTypeDef) { + .Pin = GPIO_PIN_5, + .Mode = GPIO_MODE_OUTPUT_PP, + .Pull = GPIO_NOPULL + }); + + // TODO: remove debug size + ws_backlog_alloc(24 * 60); + // ws_backlog_alloc(10); + +#ifdef WS_DBG_PRINT_ESP_OVER_USART2 + 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, (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 + do ws_esp8266_connect(); while (g_ws_server_parser.last_response == WS_SERVER_RC_ERR); + ws_esp8266_start_tcp_server(); } static void ws_io_clock_setup() { @@ -97,11 +150,27 @@ static void ws_io_i2c_setup() { static void ws_io_usart1_setup() { if (HAL_UART_Init(&huart1) != HAL_OK) return ws_setup_error_handler(); + + 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(); + + // interrupt priorities + HAL_NVIC_SetPriority(DMA1_Ch1_IRQn, 3, 0); + HAL_NVIC_EnableIRQ(DMA1_Ch1_IRQn); + HAL_NVIC_SetPriority(DMA1_Ch2_3_DMA2_Ch1_2_IRQn, 3, 0); + HAL_NVIC_EnableIRQ(DMA1_Ch2_3_DMA2_Ch1_2_IRQn); } void HAL_MspInit() { @@ -136,6 +205,14 @@ void HAL_UART_MspInit(UART_HandleTypeDef *huart) { .Alternate = GPIO_AF1_USART1, }); + // DMA setup + if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK) return ws_setup_error_handler(); + __HAL_DMA1_REMAP(HAL_DMA1_CH1_USART1_RX); + __HAL_LINKDMA(huart, hdmarx, hdma_usart1_rx); + if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK) return ws_setup_error_handler(); + __HAL_DMA1_REMAP(HAL_DMA1_CH2_USART1_TX); + __HAL_LINKDMA(huart, hdmatx, hdma_usart1_tx); + // USART1 interrupt Init HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); diff --git a/stm32f091/setup.h b/stm32f091/setup.h index 8ca3720..d459635 100644 --- a/stm32f091/setup.h +++ b/stm32f091/setup.h @@ -4,24 +4,13 @@ #include <stm32f0xx_hal_i2c.h> #include <stm32f0xx_hal_uart.h> -#define WS_PINOUT_I2C_SDA_PIN GPIO_PIN_9 -#define WS_PINOUT_I2C_SDA_PORT GPIOB -#define WS_PINOUT_I2C_SCL_PIN GPIO_PIN_8 -#define WS_PINOUT_I2C_SCL_PORT GPIOB - -#define WS_PINOUT_USART1_RX_PIN GPIO_PIN_10 -#define WS_PINOUT_USART1_RX_PORT GPIOA -#define WS_PINOUT_USART1_TX_PIN GPIO_PIN_9 -#define WS_PINOUT_USART1_TX_PORT GPIOA - -#define WS_PINOUT_USART2_RX_PIN GPIO_PIN_3 -#define WS_PINOUT_USART2_RX_PORT GPIOA -#define WS_PINOUT_USART2_TX_PIN GPIO_PIN_2 -#define WS_PINOUT_USART2_TX_PORT GPIOA +#include "consts.h" extern I2C_HandleTypeDef hi2c1; extern UART_HandleTypeDef huart1; extern UART_HandleTypeDef huart2; +extern DMA_HandleTypeDef hdma_usart1_rx; +extern DMA_HandleTypeDef hdma_usart1_tx; void ws_io_setup(); diff --git a/stm32f091/util.h b/stm32f091/util.h new file mode 100644 index 0000000..11bee6f --- /dev/null +++ b/stm32f091/util.h @@ -0,0 +1,51 @@ +#pragma once + +#include <stdlib.h> +#include <stdio.h> +#include <stm32f0xx_hal.h> +#include <string.h> + +#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 + +#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 +// #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__); \ + 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 + (color > 7 ? 6 : 0), 0x30 + (color & 0b111), 0x6d }; \ + HAL_UART_Transmit(&huart2, sgr, sizeof(sgr), 100); \ +} diff --git a/stm32f091/wifi.def.h b/stm32f091/wifi.def.h new file mode 100644 index 0000000..61e1706 --- /dev/null +++ b/stm32f091/wifi.def.h @@ -0,0 +1,7 @@ +#pragma once + +#define WS_ESP8266_WLAN_SSID "Test" +#define WS_ESP8266_WLAN_PASSWD "12345678" +// #define WS_ESP8266_WLAN_MAC "f2:9b:89:47:c4:f3" +// #define WS_ESP8266_WLAN_IP "192.168.2.69" + |