From 44bcd1c895fb34ea0a4057b9b2af21b3e95a3c14 Mon Sep 17 00:00:00 2001 From: FReenen Date: Thu, 13 Jun 2024 21:17:13 +0200 Subject: [PATCH] trying out platform io --- .gitmodules | 3 + rx_esp32/lib/cli | 1 + rx_esp32/src/CMakeLists.txt | 6 + rx_esp32/src/boats.c | 233 ++++++++++++++++++++++++++++++++++++ rx_esp32/src/boats.h | 51 ++++++++ rx_esp32/src/commands.c | 23 ++++ rx_esp32/src/commands.h | 8 ++ rx_esp32/src/main.c | 173 +++++++++++++++++++++++++- rx_esp32/src/utils.c | 39 ++++++ rx_esp32/src/utils.h | 6 + 10 files changed, 542 insertions(+), 1 deletion(-) create mode 160000 rx_esp32/lib/cli create mode 100644 rx_esp32/src/CMakeLists.txt create mode 100644 rx_esp32/src/boats.c create mode 100644 rx_esp32/src/boats.h create mode 100644 rx_esp32/src/commands.c create mode 100644 rx_esp32/src/commands.h create mode 100644 rx_esp32/src/utils.c create mode 100644 rx_esp32/src/utils.h diff --git a/.gitmodules b/.gitmodules index 5ad83ac..ffbd2e1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "rx_esp2866/lib/cli"] path = rx_esp2866/lib/cli url = git@gitea.finnvanreenen.nl:HR/EMS31_submodules.git +[submodule "rx_esp32/lib/cli"] + path = rx_esp32/lib/cli + url = git@gitea.finnvanreenen.nl:HR/EMS31_submodules.git diff --git a/rx_esp32/lib/cli b/rx_esp32/lib/cli new file mode 160000 index 0000000..09ae510 --- /dev/null +++ b/rx_esp32/lib/cli @@ -0,0 +1 @@ +Subproject commit 09ae51070be1be5ebf6717649460510dd744cf65 diff --git a/rx_esp32/src/CMakeLists.txt b/rx_esp32/src/CMakeLists.txt new file mode 100644 index 0000000..483bc0c --- /dev/null +++ b/rx_esp32/src/CMakeLists.txt @@ -0,0 +1,6 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) + +idf_component_register(SRCS ${app_sources}) diff --git a/rx_esp32/src/boats.c b/rx_esp32/src/boats.c new file mode 100644 index 0000000..6801ad6 --- /dev/null +++ b/rx_esp32/src/boats.c @@ -0,0 +1,233 @@ +#include "FIFOBuffChar.h" + +#include +#include +#include + +bool FIFOBuffChar_put(FIFOBuffChar_t *fifo, char i) // Change the function parameters to match the declaration +{ + bool ok = false; + if ((fifo->LastEl_p == NULL) && (fifo->FirstEl_p == NULL)) + { + // buffer is empty. add first element + fifo->FirstEl_p = malloc(sizeof(FIFOBuffChar_element_t)); + if (fifo->FirstEl_p != NULL) + { + fifo->FirstEl_p->character = i; // "value" to "character" + fifo->FirstEl_p->nextElement = NULL; + + fifo->LastEl_p = fifo->FirstEl_p; + fifo->size = 1; + ok = true; + } + else + { + fifo->full = true; + ok = false; + } + } + else if ((fifo->LastEl_p != NULL) && (fifo->FirstEl_p != NULL)) + { + // add element to exsiting buffer + FIFOBuffChar_element_t* el = malloc(sizeof(FIFOBuffChar_element_t)); + if (el != NULL) + { + el->character = i; // "value" to "character" + el->nextElement = NULL; + fifo->LastEl_p->nextElement = el; + fifo->LastEl_p = el; + fifo->size++; + ok = true; + } + else + { + fifo->full = true; + ok = false; + } + } + else + { + // buffer is unhealthy. try to clear it and reinit + if (fifo->FirstEl_p == NULL) + { + printf("buffer_dyn - buffer_put(): ERROR: first pointer is NULL\n"); + } + //TODO: this while loop is unsave + while (fifo->FirstEl_p != NULL) + { + FIFOBuffChar_get(fifo, NULL); // Replace buffer_get with FIFOBuffChar_get + } + if (fifo->LastEl_p != NULL) + { + free(fifo->LastEl_p); + fifo->LastEl_p = NULL; + printf("buffer_dyn - buffer_put(): ERROR: last pointer is NULL\n"); + } + FIFOBuffChar_put(fifo, i); // Replace buffer_put with FIFOBuffChar_put + ok = false; + } + return ok; +} + +bool FIFOBuffChar_get(FIFOBuffChar_t *fifo, char *p) // Change the function parameters to match the declaration +{ + bool ok = false; + if (fifo->FirstEl_p != NULL) + { + *p = fifo->FirstEl_p->character; // "value" to "character" + FIFOBuffChar_element_t* next = fifo->FirstEl_p->nextElement; + free(fifo->FirstEl_p); + // fifo->FirstEl_p = NULL; + fifo->size--; + fifo->full = false; + if (next == NULL) + { + // this was the last element in the buffer + if (fifo->LastEl_p == fifo->FirstEl_p) + { + // clear last element becouse it's the same + fifo->LastEl_p = NULL; + fifo->FirstEl_p = NULL; + fifo->size = 0; + ok = true; + } + else if (fifo->LastEl_p != NULL) + { + // buffer chain is broken; skip to last element + fifo->FirstEl_p = fifo->LastEl_p; + printf("buffer_dyn - buffer_get(): ERROR: next element is NULL, but it's not the last element. skip to last element\n"); + ok = false; + } + else + { + // somehow the last element is NULL + fifo->size = 0; + fifo->FirstEl_p = NULL; + printf("buffer_dyn - buffer_get(): ERROR: last element pointer is NULL\n"); + ok = false; + } + } + else + { + // set first element pointer to next element + fifo->FirstEl_p = next; + ok = true; + } + } + else + { + ok = false; + } + return ok; +} + +bool FIFOBuffChar_pop(FIFOBuffChar_t *fifo) +{ + bool ok = true; + + switch (fifo->size){ + case 0: // buffer is empty + ok = false; + break; + + case 1: // singel item in buffer + // make buffer empty + free(fifo->FirstEl_p); + fifo->FirstEl_p = NULL; + fifo->LastEl_p = NULL; + fifo->size = 0; + ok = true; + break; + + default: // buffer is at least 2 element big + // find the second last element + { + FIFOBuffChar_element_t* secondLastEl = fifo->FirstEl_p; + while ( + secondLastEl->nextElement != fifo->LastEl_p + && ((FIFOBuffChar_element_t*)secondLastEl->nextElement)->nextElement != NULL + ){ + secondLastEl = secondLastEl->nextElement; + } + + // remove last element + free(fifo->LastEl_p); + + // update chain + secondLastEl->nextElement = NULL; + fifo->LastEl_p = secondLastEl; + fifo->size--; + ok = true; + break; + } + } + + return ok; +} + +bool FIFOBuffChar_is_full(FIFOBuffChar_t *fifo) +{ + return fifo->full; +} + +bool FIFOBuffChar_is_empty(FIFOBuffChar_t *fifo) +{ + // printf("empty %s: %s; fifo->LastEl_p = %i; fifo->FirstEl_p = %i\n", + // (fifo->LastEl_p == NULL) && (fifo->FirstEl_p == NULL) ? "true" : "false", + // (fifo->LastEl_p == fifo->FirstEl_p) ? "same" : "diff", + // (int) fifo->LastEl_p, + // (int) fifo->FirstEl_p); + return ((fifo->LastEl_p == NULL) && (fifo->FirstEl_p == NULL)); +} + + +FIFOBuffChar_t* FIFOBuffChar_create(void) +{ + + // Allocate memory for a new FIFOBuffChar_t + FIFOBuffChar_t* fifo = malloc(sizeof(FIFOBuffChar_t)); + + if (fifo == NULL) { + // Memory allocation failed + return NULL; + } + + // Initialize the FIFO buffer + // Point the last element to the first one + // Initialize other fields of the FIFOBuffChar_t struct + + fifo->FirstEl_p = NULL; + fifo->LastEl_p = NULL; + fifo->size = 0; + fifo->full = false; + + return fifo; + +} + + +bool FIFOBuffChar_delete(FIFOBuffChar_t *fifo) +{ + + // Check if the buffer is already empty + if (fifo->FirstEl_p == NULL) + { + // Delete all elements in the buffer + FIFOBuffChar_element_t* currentElement = fifo->FirstEl_p; + while (currentElement != NULL) + { + FIFOBuffChar_element_t* nextElement = currentElement->nextElement; + free(currentElement); + currentElement = nextElement; + } + } + + free(fifo); + return true; +} + + +unsigned int FIFOBuffChar_getSize(FIFOBuffChar_t *fifo) +{ + return fifo->size; +} diff --git a/rx_esp32/src/boats.h b/rx_esp32/src/boats.h new file mode 100644 index 0000000..8008575 --- /dev/null +++ b/rx_esp32/src/boats.h @@ -0,0 +1,51 @@ +#ifndef BOATS_h +#define BOATS_h + +#include +#include +#include + +typedef struct Boats_s { + uint16_t id; + char* name; + bool avaliable; + bool locked; +} Boats_t; + +typedef struct BoatsDB_el_s { + Boats_t boat; + void* nextEl; +} BoatsDB_el_t; + +// defines all vars for the buffer to operate +typedef struct BoatsDB_s { + BoatsDB_el_t* FirstEl_p; + BoatsDB_el_t* LastEl_p; + unsigned char size; + bool full; +} BoatsDB_t; + +// create a fifo buffer and initilizes it with zeros +extern BoatsDB_t* BoatsDB_init(); + +// destroy a fifo buffer (free up its space) +// returns true on success or false otherways +extern bool BoatsDB_deinit(BoatsDB_t* fifo); + +// put value i in buffer if there is still memory avaliable +// returns true on success or false otherways +extern bool BoatsDB_put(BoatsDB_t *fifo, char i); + +// get value from buffer and writes it to *p if buffer not empty +// returns true on success or false otherways +extern bool BoatsDB_getById(BoatsDB_t *fifo, uint16_t id, ); + +// returns false if last put fails to gain memory and no get is called afterwards or true otherwise +extern bool BoatsDB_is_full(BoatsDB_t *fifo); + +// returns true when buffer is empty or false otherways +extern bool BoatsDB_is_empty(BoatsDB_t *fifo); + +extern unsigned int BoatsDB_getSize(BoatsDB_t *fifo); + +#endif \ No newline at end of file diff --git a/rx_esp32/src/commands.c b/rx_esp32/src/commands.c new file mode 100644 index 0000000..4660652 --- /dev/null +++ b/rx_esp32/src/commands.c @@ -0,0 +1,23 @@ + +#include "../lib/cli/CMDList/CMDList.h" + +#include "commands.h" + +int contrl(char* line) +{ + +} + +const CMD_t Commands[] = { + { "ctrl", &contrl } +}; + +CMDList_t* getCMDList() +{ + CMDList_t* list = CMDList_init(); + for (int i = sizeof(Commands) / sizeof(CMD_t); i >= 0; i--) + { + CMDList_add(list, (CMD_t*)&Commands[i], Commands[i].cmd); + } + return list; +} diff --git a/rx_esp32/src/commands.h b/rx_esp32/src/commands.h new file mode 100644 index 0000000..f0fabdd --- /dev/null +++ b/rx_esp32/src/commands.h @@ -0,0 +1,8 @@ +#ifndef COMMAND_H +#define COMMAND_H + +#include "../lib/cli/CMDList/CMDList.h" + +extern CMDList_t* getCMDList(); + +#endif diff --git a/rx_esp32/src/main.c b/rx_esp32/src/main.c index 36b5510..f2b34c6 100644 --- a/rx_esp32/src/main.c +++ b/rx_esp32/src/main.c @@ -1 +1,172 @@ -void app_main() {} +#include +#include + +#include "nvs_flash.h" +#include "esp_log.h" +#include "esp_wifi.h" +#include "esp_event.h" + +#include "../lib/cli/CLI/CLI.h" +#include "../lib/cli/CMDList/CMDList.h" + +#include "commands.h" + +#define WIFI_SSID "UPC46273" +#define WIFI_PASS "SPHZHKRY" +#define UDP_PORT 1234 + +static const char *TAG = "FR_rx-esp32"; + +#define MAX_RETRY_ATTEMPTS 2 +static int s_ap_creds_num = 0; +static int s_retry_num = 0; + +uint8_t BoatId = 1; + +bool running = true; +CMDList_t* cmdList; + +bool rxBuffer_overflow = false; + +static EventGroupHandle_t s_wifi_event_group; +/* The event group allows multiple bits for each event, but we only care about two events: + * - we are connected to the AP with an IP + * - we failed to connect after the maximum amount of retries */ +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +/* + * CLI char out function. used to print back to a CLI, but the lib + * is only used for reciving command and not having a full cli + */ +int charOut(const char* line) +{ + // don't print anything + return 0; +} + +static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) + { + esp_wifi_connect(); + } + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) + { + if (s_retry_num < MAX_RETRY_ATTEMPTS) + { + esp_wifi_connect(); + s_retry_num++; + ESP_LOGI(TAG, "retry to connect to the AP"); + } + else + { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(TAG,"connect to the AP fail"); + } + else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) + { + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +void app_main() { + /* Initialize NVS — it is used to store PHY calibration data */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + s_wifi_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + NULL, + &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &event_handler, + NULL, + &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = { + .ssid = WIFI_SSID, + .password = WIFI_PASS, + /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8). + * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value + * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to + * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards. + */ + .threshold.authmode = WIFI_AUTH_WPA_WPA2_PSK, + .sae_pwe_h2e = WPA3_SAE_PWE_HUNT_AND_PECK, + .sae_h2e_identifier = "", + }, + }; + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_LOGI(TAG, "wifi_init_sta finished."); + + /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum + * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + * happened. */ + if (bits & WIFI_CONNECTED_BIT) { + ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", WIFI_SSID, WIFI_PASS); + } else if (bits & WIFI_FAIL_BIT) { + ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", WIFI_SSID, WIFI_PASS); + } else { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); + } + + // running = true; + + // cmdList = getCMDList(); + + // // init cli + // CLI_init((CLI_charOutFn)&charOut, cmdList); + + // while (running) + // { + // int packetSize = UDP.parsePacket(); + // while (packetSize) { + // char c; + // int len = UDP.read(&c, 1); + // if (len == 1) + // { + // CLI_charIn(c); + // packetSize -= c; + // } + // } + // } + + // CLI_deinit(); + // CMDList_deinit(cmdList); + + return; +} diff --git a/rx_esp32/src/utils.c b/rx_esp32/src/utils.c new file mode 100644 index 0000000..fe7f37b --- /dev/null +++ b/rx_esp32/src/utils.c @@ -0,0 +1,39 @@ +#include "utils.h" + +#include +#include + +char* getNextArg(char* args) +{ + uint8_t step = 0; + int end = 0; + while (end == 0) + { + if (step < 255) + { + switch (*(args + step)) + { + case ';': + end = 1; // found + case '\n': + case '\r': + case '\0': + end = 2; // end of line + } + } + else + { + end = 3; // line to long + } + step++; + } + + if (end != 3) + { + return args + step; + } + else + { + return NULL; + } +} diff --git a/rx_esp32/src/utils.h b/rx_esp32/src/utils.h new file mode 100644 index 0000000..dfb488e --- /dev/null +++ b/rx_esp32/src/utils.h @@ -0,0 +1,6 @@ +#ifndef UTILS_H +#define UTILS_H + +char* getNextArg(char* args); + +#endif \ No newline at end of file