aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUnavailableDev <69792062+UnavailableDev@users.noreply.github.com>2022-10-30 17:42:03 +0100
committerGitHub <noreply@github.com>2022-10-30 17:42:03 +0100
commitb82a9c44d0112f5433c4482e2e5802969515ce7d (patch)
tree907451385d246dc61b513f3a27043f32b058268a
parent84341bc53bca3da581ba59f66bf4174420c83d3a (diff)
parentfc95a016d13c1510a024888c1b87bbfe1a7f7601 (diff)
Merge branch 'dev' into qt-settings
-rw-r--r--client/Client.cpp65
-rw-r--r--client/Client.h2
-rw-r--r--client/HandleMessage.cpp21
-rw-r--r--client/HandleMessage.h2
-rw-r--r--makefile6
-rw-r--r--shared/protocol.h2
-rw-r--r--shared/util.c26
-rw-r--r--shared/util.h17
-rw-r--r--stm32f091/consts.h2
-rw-r--r--stm32f091/protocol.c4
-rw-r--r--stm32f091/sensor.c15
-rw-r--r--stm32f091/server.c24
-rw-r--r--stm32f091/server.h65
-rw-r--r--stm32f091/setup.c6
-rw-r--r--stm32f091/setup.h8
-rw-r--r--stm32f091/util.h3
-rw-r--r--todo.md12
17 files changed, 163 insertions, 117 deletions
diff --git a/client/Client.cpp b/client/Client.cpp
index 87afe99..2075fc2 100644
--- a/client/Client.cpp
+++ b/client/Client.cpp
@@ -18,46 +18,49 @@ Client::~Client()
delete timer;
}
-void Client::ClientEcho()
-{
-
- connect(timer, SIGNAL(timeout()),this,SLOT(timeFunction())); // connect timer to time every minute
-
- // connect to readyread to receive data;
- connect(socket,&QTcpSocket::readyRead, [&]() {
- QTextStream T(socket);
- QString text = T.readAll(); // reads all data
- Handlemsg.ParseToSQL(Handlemsg.ParseMessage(text, (totalRecords-'0')));
-
-
- });
-
- timer->start(1000);
+void Client::ClientEcho() {
+ static unsigned int lineCounter = 0;
+ connect(timer, SIGNAL(timeout()),this,SLOT(timeFunction())); // connect timer to time every minute
+
+ // connect to readyread to receive data;
+ connect(socket,&QTcpSocket::readyRead, [&]() {
+ QTextStream T(socket);
+ QString text = T.readAll(); // reads all data
+ lineCounter++;
+ if (lineCounter <= 2) return;
+ Handlemsg.ParseToSQL(text);
+ });
+
+ connect(socket, &QTcpSocket::disconnected, [&]() {
+ socket->disconnectFromHost();
+ lineCounter = 0;
+ });
+
+ timer->start(1000);
}
-void Client::timeFunction()
-{
- totalRecords = WS_MAX(1, _missingRecords);
+void Client::timeFunction() {
+ if((QTime::currentTime().second() % WS_CLIENT_STATION_POLL_INTERVAL) != 0) return;
- char* msg = NULL;
- asprintf(&msg, "last-records %x %x\n", totalRecords, offsetRecords);
- QByteArray msgToSend = msg;
- free(msg);
+ this->missingRecords();
+ totalRecords = WS_MIN(WS_MAX(1, _missingRecords), 50);
- QTime time = QTime::currentTime();
- qint16 currentSeconds = time.second();
- if((currentSeconds % WS_CLIENT_STATION_POLL_INTERVAL) == 1){
+ char* msg = NULL;
+ asprintf(&msg, "last-records %x %x\n", totalRecords, offsetRecords);
+ QByteArray msgToSend = msg;
+ free(msg);
- socket->connectToHost(networkAddress, tcpPortAddress);
- socket->write(msgToSend);
- }
+ socket->connectToHost(networkAddress, tcpPortAddress);
+ socket->write(msgToSend);
}
void Client::missingRecords()
{
QSqlQuery queryTimeData;
- queryTimeData.exec( "SELECT (unix_timestamp(now()) - unix_timestamp(`time`))/60 as delta FROM `tblMain` limit 1");
-
- _missingRecords = queryTimeData.value(0).toInt();
+ queryTimeData.exec("SELECT (unix_timestamp(now()) - unix_timestamp(`time`))/60 as delta FROM `tblMain` limit 1");
+ queryTimeData.first();
+ unsigned int secondsSinceLastRecord = queryTimeData.value(0).toInt();
+ _missingRecords = secondsSinceLastRecord / WS_CLIENT_STATION_POLL_INTERVAL;
}
+
diff --git a/client/Client.h b/client/Client.h
index b90e5e9..433aecf 100644
--- a/client/Client.h
+++ b/client/Client.h
@@ -25,7 +25,7 @@ public slots:
private:
void missingRecords();
- int _missingRecords;
+ int _missingRecords = 0;
QTcpSocket *socket; // tcpsocket for communicating
QTimer *timer; // timer to read every second what time it curruntly is.
diff --git a/client/HandleMessage.cpp b/client/HandleMessage.cpp
index 3d8823b..399abe8 100644
--- a/client/HandleMessage.cpp
+++ b/client/HandleMessage.cpp
@@ -1,17 +1,22 @@
#include "HandleMessage.h"
-HandleMessage::HandleMessage(QObject *parent) : QObject(parent)
-{
+HandleMessage::HandleMessage(QObject *parent) : QObject(parent) { }
-}
+void HandleMessage::ParseToSQL(QString input) {
+ QSqlQuery queryInsertData;
+ QString output = "insert into WSdb.tblMain (temperature, humidity, pressure) values ";
+ QStringList data;
-QString HandleMessage::ParseMessage(const QString Msg , int totalRecords )
-{
- QString message= Msg.section('\n',2,(3+totalRecords));
+ output.append("(");
+ data=input.split(",");
- return message;
+ for (int i = 1; i < data.size(); i++) {
+ bool valid;
+ output.append(QString::number(data[i].toInt(&valid, 16)));
+ if (i + 1 < data.size()) output.append(",");
+ }
-}
+ output.append(")");
void HandleMessage::ParseToSQL(QString input)
{
diff --git a/client/HandleMessage.h b/client/HandleMessage.h
index f228633..f5995c7 100644
--- a/client/HandleMessage.h
+++ b/client/HandleMessage.h
@@ -12,8 +12,6 @@ class HandleMessage : public QObject
Q_OBJECT
public:
HandleMessage(QObject *parent = 0);
-
- QString ParseMessage(const QString , int);
void ParseToSQL(QString);
private:
diff --git a/makefile b/makefile
index 60e06ef..31ff4bf 100644
--- a/makefile
+++ b/makefile
@@ -8,10 +8,10 @@ client_makefile:
qmake client/client.pro -o client/makefile
client: client_makefile
- make -C client
+ make -j -C client
client_compile_commands: client_makefile
- compiledb -o client/compile_commands.json make -C client
+ compiledb -o client/compile_commands.json make -BnC client
stm32:
- make -C stm32f091
+ make -j -C stm32f091
diff --git a/shared/protocol.h b/shared/protocol.h
index 96c039a..e5ddf05 100644
--- a/shared/protocol.h
+++ b/shared/protocol.h
@@ -148,4 +148,6 @@ 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,
};
+/** @brief return length of custom protocol header */
unsigned short ws_protocol_get_header_size(ws_s_protocol_res* response);
+
diff --git a/shared/util.c b/shared/util.c
index ea972b0..648631a 100644
--- a/shared/util.c
+++ b/shared/util.c
@@ -4,4 +4,28 @@ 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
+}
+
+uint8_t ws_sensor_tmp_to_8(uint16_t temperature) {
+ return temperature / 256;
+}
+
+uint8_t ws_sensor_hum_to_8(uint16_t humidity) {
+ return humidity / 256;
+}
+
+uint8_t ws_sensor_atm_to_8(uint16_t atmospheric_pressure) {
+ return atmospheric_pressure / 256;
+}
+
+float ws_sensor_tmp_to_f(uint8_t temperature) {
+ return ((175.72 * temperature) / 256.0) - 46.85;
+}
+
+float ws_sensor_hum_to_f(uint8_t humidity) {
+ return ((125.0 * humidity) / 256.0) - 6.0;
+}
+
+float ws_sensor_atm_to_f(uint8_t atmospheric_pressure) {
+ return ((20.0 * atmospheric_pressure) / 256.0) + 990.0; // datasheet no?
+}
diff --git a/shared/util.h b/shared/util.h
index 94a3dfe..1bee487 100644
--- a/shared/util.h
+++ b/shared/util.h
@@ -1,6 +1,23 @@
#pragma once
+#include <stdint.h>
+
#define WS_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define WS_MAX(a, b) (((a) > (b)) ? (a) : (b))
+/** @brief take the log base 16 of `x` */
unsigned int ws_log16(unsigned int x);
+
+/** @brief convert 16-bit temperature value to uint8_t */
+uint8_t ws_sensor_tmp_to_8(uint16_t temperature);
+/** @brief convert 16-bit humidity value to uint8_t */
+uint8_t ws_sensor_hum_to_8(uint16_t humidity);
+/** @brief convert 16-bit atmospheric pressure value to uint8_t */
+uint8_t ws_sensor_atm_to_8(uint16_t atmospheric_pressure);
+
+/** @brief convert 8-bit temperature value back to float */
+float ws_sensor_tmp_to_f(uint8_t temperature);
+/** @brief convert 8-bit humidity value back to float */
+float ws_sensor_hum_to_f(uint8_t humidity);
+/** @brief convert 8-bit atmospheric pressure value back to float */
+float ws_sensor_atm_to_f(uint8_t atmospheric_pressure);
diff --git a/stm32f091/consts.h b/stm32f091/consts.h
index 6d5b8d2..2a09508 100644
--- a/stm32f091/consts.h
+++ b/stm32f091/consts.h
@@ -9,6 +9,8 @@
#define WS_DMA_RX_BUFFER_SIZE 100
#define WS_DMA_TX_BUFFER_SIZE 1024
+#define WS_BACKLOG_SIZE (24 * 60)
+
#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
diff --git a/stm32f091/protocol.c b/stm32f091/protocol.c
index f4be08f..405ceb8 100644
--- a/stm32f091/protocol.c
+++ b/stm32f091/protocol.c
@@ -7,7 +7,7 @@
#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_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");
@@ -21,7 +21,7 @@ void ws_protocol_res_last_records(ws_s_protocol_parsed_req_cmd* parsed_cmd, ws_s
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);
+ record_amount = WS_MAX(0, (int) record_amount - (int) record_offset);
response->msg->bytes = strlen(response_header) + response_line_len * record_amount;
}
} else {
diff --git a/stm32f091/sensor.c b/stm32f091/sensor.c
index 1c94e2a..3695939 100644
--- a/stm32f091/sensor.c
+++ b/stm32f091/sensor.c
@@ -13,42 +13,33 @@
uint8_t ws_sensor_temperature() {
uint8_t buf[12];
- int16_t val;
- float temp_c;
buf[0] = SI7021_REG_TEMP;
HAL_I2C_Master_Transmit(&hi2c1, SI7021_ADDRESS, buf, 1, HAL_MAX_DELAY);
HAL_I2C_Master_Receive(&hi2c1, SI7021_ADDRESS, buf, 2, HAL_MAX_DELAY);
- val = ((int16_t)buf[0]<< 8 ) | (buf[1]);
- temp_c= ((175.72*val)/65536) - 46.85;
- return (uint8_t) temp_c; //TODO: convert with range -> util.h
+ return ws_sensor_tmp_to_8(((int16_t)buf[0]<< 8 ) | (buf[1]));
}
uint8_t ws_sensor_humidity() {
uint8_t buf[12];
- int16_t val;
buf[0] = SI7021_REG_HUM;
HAL_I2C_Master_Transmit(&hi2c1, SI7021_ADDRESS, buf, 1, HAL_MAX_DELAY);
HAL_I2C_Master_Receive(&hi2c1, SI7021_ADDRESS, buf, 2, HAL_MAX_DELAY);
- val = ((int16_t)buf[0]<< 8 ) | (buf[1]);
- float humidity = (( 125 * (float) val ) / 65536 ) - 6;
- return (uint8_t) humidity; //TODO: convert with range -> util.h
+ return ws_sensor_hum_to_8(((int16_t)buf[0]<< 8 ) | (buf[1]));
}
uint8_t ws_sensor_atmospheric_pressure() {
uint8_t buf[12];
uint8_t buffer[12];
- int16_t val;
buf[0]= 0xF4;
buf[1]= 0x07;
buffer[0] = 0xF7;
HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDRESS, buf , 2, HAL_MAX_DELAY);
HAL_I2C_Mem_Read(&hi2c1, BMP280_ADDRESS, 0xF7, 1, buffer, 2, 100 );
- val = (buffer[0] << 8 | buffer[1]);
- return (uint8_t) val; // TODO: convert with range
+ return ws_sensor_atm_to_8((uint16_t) buffer[0] << 8 | buffer[1]);
}
void ws_sensor_read() {
diff --git a/stm32f091/server.c b/stm32f091/server.c
index d69ef1e..1d4a469 100644
--- a/stm32f091/server.c
+++ b/stm32f091/server.c
@@ -162,9 +162,8 @@ 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_head], (char*) data, size); // append string
+ size_t limited_size = WS_MIN(size, g_ws_esp8266_dma_tx_buffer_head - g_ws_esp8266_dma_tx_buffer_tail);
+ strncpy((char*) &g_ws_esp8266_dma_tx_buffer[g_ws_esp8266_dma_tx_buffer_head], (char*) data, limited_size); // append string
g_ws_esp8266_dma_tx_buffer_head += size; // shift head
}
@@ -201,24 +200,5 @@ void ws_server_buffer_send_chunk() {
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 07c49d9..ba92b78 100644
--- a/stm32f091/server.h
+++ b/stm32f091/server.h
@@ -4,6 +4,7 @@
#include <stdint.h>
#include <stdbool.h>
+/** @brief store kind of AT command response the server is expecting */
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 */
@@ -12,39 +13,43 @@ typedef enum {
WS_SERVER_LM_CIPSEND_LISTENING, /** @brief AT+CIPSEND sent, now reading data */
} ws_e_server_listen_mode;
+/** @brief state machine for parsing +IPD command fields */
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;
+/** @brief AT command status codes */
typedef enum {
- WS_SERVER_RC_NONE = -1,
- WS_SERVER_RC_BUSY,
- WS_SERVER_RC_ERR,
- WS_SERVER_RC_OK,
+ WS_SERVER_RC_NONE = -1, /** @brief initial value */
+ WS_SERVER_RC_BUSY, /** @brief status code busy p... */
+ WS_SERVER_RC_ERR, /** @brief status code ERROR */
+ WS_SERVER_RC_OK, /** @brief status code OK */
} ws_e_server_response_code;
+/** @brief counters for byte-by-byte string comparison of AT response codes */
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 */
+ uint8_t s_ok; /** @brief counter for status code OK */
+ uint8_t s_error; /** @brief counter for status code OK */
+ uint8_t s_fail; /** @brief counter for status code OK */
+ uint8_t s_busy; /** @brief counter for status code OK */
+ uint8_t i_ipd; /** @brief counter for idle +IPD, */
+ uint8_t i_prompt; /** @brief counter for idle > */
+ uint8_t l_send_ok; /** @brief counter for ipd listen SEND OK */
+ uint8_t l_error; /** @brief counter for ipd listen ERROR */
} ws_s_server_parser_response_counter;
+/** @brief server parser statue struct */
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_e_server_listen_mode mode; /** @brief expected AT response kind */
+ ws_e_server_response_code last_response; /** @brief response code for last AT command */
+ unsigned int current_channel; /** @brief TCP channel for last +IPD command */
+ unsigned int channel_data_length; /** @brief data length for last +IPD command */
+ unsigned int channel_data_counter; /** @brief amount of parsed data bytes for last +IPD command */
+ ws_e_channel_listen_mode channel_listen_mode; /** @brief +IPD command parse state */
+ bool channel_data_ignore; /** @brief whether last TCP request should be ignored because it's too long */
+ ws_s_server_parser_response_counter rc; /** @brief response counters for byte-by-byte string comparison */
} ws_s_server_parser;
/** @brief global server parser struct */
@@ -62,11 +67,6 @@ 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);
-// /** @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);
@@ -93,7 +93,22 @@ void ws_server_req_parse_byte(unsigned int channel, uint8_t byte, bool ignore);
*/
void ws_server_req_finish(unsigned int channel, bool ignore);
+/**
+ * @brief append data to the tx buffer for sending response in chunks
+ *
+ * the esp8266 becomes unreliable when sending large tcp responses, so this
+ * function buffers the complete response, and sends it in chunks broken up by
+ * a newline ('\n') character
+ *
+ * to send data buffered using this function, refer to
+ * `ws_server_buffer_request_chunk_send` and `ws_server_buffer_send_chunk`.
+ *
+ * @param data pointer to data array
+ * @param size size of data array
+ */
void ws_server_buffer_send_append(uint8_t* data, size_t size);
+/** @brief send AT+CIPSEND with size of next chunk to the esp8266 */
void ws_server_buffer_request_chunk_send();
+/** @brief send data chunk for last AT+CIPSEND command */
void ws_server_buffer_send_chunk();
diff --git a/stm32f091/setup.c b/stm32f091/setup.c
index ef00a29..658e1bb 100644
--- a/stm32f091/setup.c
+++ b/stm32f091/setup.c
@@ -92,9 +92,7 @@ void ws_io_setup() {
.Pull = GPIO_NOPULL
});
- // TODO: remove debug size
- ws_backlog_alloc(24 * 60);
- // ws_backlog_alloc(10);
+ ws_backlog_alloc(WS_BACKLOG_SIZE);
#ifdef WS_DBG_PRINT_ESP_OVER_USART2
ws_dbg_set_usart2_tty_color(WS_DBG_TTY_COLOR_DBGMSG);
@@ -184,7 +182,7 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) {
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_Init(GPIOB, &(GPIO_InitTypeDef) {
- .Pin = GPIO_PIN_8|GPIO_PIN_9, //TODO: use #defines in setup.h
+ .Pin = WS_PINOUT_I2C_SCL_PIN | WS_PINOUT_I2C_SDA_PIN,
.Mode = GPIO_MODE_AF_OD,
.Pull = GPIO_NOPULL,
.Speed = GPIO_SPEED_FREQ_HIGH,
diff --git a/stm32f091/setup.h b/stm32f091/setup.h
index d459635..2d34952 100644
--- a/stm32f091/setup.h
+++ b/stm32f091/setup.h
@@ -6,17 +6,25 @@
#include "consts.h"
+/** @brief glbal HAL i2c-1 state */
extern I2C_HandleTypeDef hi2c1;
+/** @brief glbal HAL uart-1 state */
extern UART_HandleTypeDef huart1;
+/** @brief glbal HAL uart-1 state */
extern UART_HandleTypeDef huart2;
+/** @brief glbal HAL DMA state for uart-1's RX channel */
extern DMA_HandleTypeDef hdma_usart1_rx;
+/** @brief glbal HAL DMA state for uart-1's TX channel */
extern DMA_HandleTypeDef hdma_usart1_tx;
+/** @brief "main" setup function */
void ws_io_setup();
+// required HAL setup functions
void NMI_Handler();
void HardFault_Handler();
void SysTick_Handler();
void HAL_MspInit();
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c);
void HAL_UART_MspInit(UART_HandleTypeDef *huart);
+
diff --git a/stm32f091/util.h b/stm32f091/util.h
index 9c15f8b..100b877 100644
--- a/stm32f091/util.h
+++ b/stm32f091/util.h
@@ -34,6 +34,7 @@
#define WS_DBG_TTY_COLOR_TX WS_DBG_TTY_COLOR_GRN
#define WS_DBG_TTY_COLOR_RX WS_DBG_TTY_COLOR_RED
+// allow `debugger;` statement like in JS
#define debugger asm("nop")
// unused
@@ -43,12 +44,14 @@
// #define WS_DBG_TTY_COLOR_IPD_LISTENING WS_DBG_TTY_COLOR_GRN
// #define WS_DBG_TTY_COLOR_CIPSEND_LISTENING WS_DBG_TTY_COLOR_RED
+/** @brief `printf()` over uart2 (usb) */
#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); \
}
+/** @brief print VT100 escape code over uart2 to set tty color */
#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/todo.md b/todo.md
index 5924b20..150e12c 100644
--- a/todo.md
+++ b/todo.md
@@ -16,13 +16,13 @@
## `// TODO:`'s
-- [ ] `sensor.c:24: return (uint8_t) temp_c; //TODO: convert with range -> util.h`
-- [ ] `sensor.c:36: return (uint8_t) humidity; //TODO: convert with range -> util.h`
-- [ ] `sensor.c:51: return (uint8_t) val; // TODO: convert with range`
+- [x] `sensor.c:24: return (uint8_t) temp_c; //TODO: convert with range -> util.h`
+- [x] `sensor.c:36: return (uint8_t) humidity; //TODO: convert with range -> util.h`
+- [x] `sensor.c:51: return (uint8_t) val; // TODO: convert with range`
- [x] `server.c:47:// TODO: next_few_bytes_are assumes that the complete search string is in the`
-- [ ] `server.c:146: // TODO: buffer overrun protection`
+- [x] `server.c:146: // TODO: buffer overrun protection`
- [x] `server.c:152:// TODO: refactor this`
- [x] `server.c:165:// TODO: refactor this`
- [x] `server.c:174:// TODO: refactor this`
-- [ ] `setup.c:95: // TODO: remove debug size`
-- [ ] `setup.c:187: .Pin = GPIO_PIN_8|GPIO_PIN_9, //TODO: use #defines in setup.h`
+- [x] `setup.c:95: // TODO: remove debug size`
+- [x] `setup.c:187: .Pin = GPIO_PIN_8|GPIO_PIN_9, //TODO: use #defines in setup.h`