diff --git a/rx_esp32/.gitignore b/rx_esp32/.gitignore index 89cc49c..57c8cfa 100644 --- a/rx_esp32/.gitignore +++ b/rx_esp32/.gitignore @@ -3,3 +3,5 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch + +build \ No newline at end of file diff --git a/rx_esp32/include/README b/rx_esp32/include/README deleted file mode 100644 index 194dcd4..0000000 --- a/rx_esp32/include/README +++ /dev/null @@ -1,39 +0,0 @@ - -This directory is intended for project header files. - -A header file is a file containing C declarations and macro definitions -to be shared between several project source files. You request the use of a -header file in your project source file (C, C++, etc) located in `src` folder -by including it, with the C preprocessing directive `#include'. - -```src/main.c - -#include "header.h" - -int main (void) -{ - ... -} -``` - -Including a header file produces the same results as copying the header file -into each source file that needs it. Such copying would be time-consuming -and error-prone. With a header file, the related declarations appear -in only one place. If they need to be changed, they can be changed in one -place, and programs that include the header file will automatically use the -new version when next recompiled. The header file eliminates the labor of -finding and changing all the copies as well as the risk that a failure to -find one copy will result in inconsistencies within a program. - -In C, the usual convention is to give header files names that end with `.h'. -It is most portable to use only letters, digits, dashes, and underscores in -header file names, and at most one dot. - -Read more about using header files in official GCC documentation: - -* Include Syntax -* Include Operation -* Once-Only Headers -* Computed Includes - -https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/rx_esp32/src/CMakeLists.txt b/rx_esp32/src/CMakeLists.txt index 483bc0c..d8744f5 100644 --- a/rx_esp32/src/CMakeLists.txt +++ b/rx_esp32/src/CMakeLists.txt @@ -1,6 +1,6 @@ # This file was automatically generated for projects # without default 'CMakeLists.txt' file. -FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*) +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.c) idf_component_register(SRCS ${app_sources}) diff --git a/rx_esp32/src/commands.c b/rx_esp32/src/commands.c index 7b09665..ee964c5 100644 --- a/rx_esp32/src/commands.c +++ b/rx_esp32/src/commands.c @@ -100,8 +100,8 @@ int setLed(char* line, CLI_t* cli) led_setRGB(r, g, b); - char msg[20]; - snprintf(&msg[0], 20, "led: r%d g%d n%d\n", r, g, b); + char msg[30]; + snprintf(&msg[0], 30, "led: r%d g%d n%d\n", r, g, b); CLI_stringOut(cli, &msg[0]); return 0; } diff --git a/rx_esp32/src/config.h b/rx_esp32/src/config.h index 8c2cd44..4a88a4d 100644 --- a/rx_esp32/src/config.h +++ b/rx_esp32/src/config.h @@ -3,10 +3,13 @@ #include -#define WIFI_SSID "UPC46273" -// #define WIFI_AUTH WIFI_AUTH_WPA_WPA2_PSK -#define WIFI_AUTH WIFI_AUTH_WPA_PSK -#define WIFI_PASS "SPHZHKRY" +// #define WIFI_SSID "UPC46273" +// #define WIFI_AUTH WIFI_AUTH_WPA_PSK +// #define WIFI_PASS "SPHZHKRY" +#define WIFI_SSID "Wifi Ding" +#define WIFI_AUTH WIFI_AUTH_WPA_WPA2_PSK +#define WIFI_PASS "Weet ik niet." + #define UDP_PORT 1234 static uint8_t BoatId = 1; diff --git a/rx_esp32/src/led.c b/rx_esp32/src/led.c index 5e63ba9..e0f94c6 100644 --- a/rx_esp32/src/led.c +++ b/rx_esp32/src/led.c @@ -1,5 +1,7 @@ #include "led.h" +#include + #include #include "driver/rmt_tx.h" #include "driver/rmt_types.h" @@ -7,20 +9,73 @@ #include "driver/gpio.h" typedef struct { - rmt_encoder_t base; - rmt_encoder_t *bytes_encoder; - rmt_encoder_t *copy_encoder; - int state; - rmt_symbol_word_t reset_code; + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int state; + rmt_symbol_word_t reset_code; } rmt_led_strip_encoder_t; rmt_channel_handle_t led_rmt_channel; -rmt_led_strip_encoder_t* led_enc; +rmt_led_strip_encoder_t led_enc; -rmt_led_strip_encoder_t* led_init_encoder() +static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { - rmt_led_strip_encoder_t* led_encoder; - led_encoder = calloc(1, sizeof(rmt_led_strip_encoder_t)); + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encode_state_t session_state = 0; + rmt_encode_state_t state = 0; + size_t encoded_symbols = 0; + switch (led_encoder->state) { + case 0: // send RGB data + encoded_symbols += led_encoder->bytes_encoder->encode(led_encoder->bytes_encoder, channel, primary_data, data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 1; // switch to next state when current encoding session finished + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts + } + // fall-through + case 1: // send reset code + encoded_symbols += led_encoder->copy_encoder->encode(led_encoder->copy_encoder, channel, &led_encoder->reset_code, + sizeof(led_encoder->reset_code), &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 0; // back to the initial encoding session + state |= RMT_ENCODING_COMPLETE; + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts + } + } +out: + *ret_state = state; + return encoded_symbols; +} + +static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_del_encoder(led_encoder->bytes_encoder); + rmt_del_encoder(led_encoder->copy_encoder); + free(led_encoder); + return ESP_OK; +} + +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_reset(led_encoder->bytes_encoder); + rmt_encoder_reset(led_encoder->copy_encoder); + led_encoder->state = 0; + return ESP_OK; +} + +void led_init_encoder() +{ + led_enc.base.encode = rmt_encode_led_strip; + led_enc.base.del = rmt_del_led_strip_encoder; + led_enc.base.reset = rmt_led_strip_encoder_reset; rmt_bytes_encoder_config_t bytes_encoder_config; // different led strip might have its own timing requirements, following parameter is for WS2812 @@ -40,18 +95,17 @@ rmt_led_strip_encoder_t* led_init_encoder() .flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0 }; - rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder); - // rmt_copy_encoder_config_t copy_encoder_config = {}; - // rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder); + rmt_new_bytes_encoder(&bytes_encoder_config, &led_enc.bytes_encoder); + rmt_copy_encoder_config_t copy_encoder_config = {}; + rmt_new_copy_encoder(©_encoder_config, &led_enc.copy_encoder); uint32_t reset_ticks = 10 /*MHz*/ * 280 / 2; // reset code duration defaults to 280us to accomodate WS2812B-V5 - led_encoder->reset_code = (rmt_symbol_word_t) { + led_enc.reset_code = (rmt_symbol_word_t) { .level0 = 0, .duration0 = reset_ticks, .level1 = 0, .duration1 = reset_ticks, }; - return led_encoder; } void led_init(void) @@ -67,7 +121,7 @@ void led_init(void) .flags.invert_out = false, }; rmt_new_tx_channel(&rmt_chan_config, &led_rmt_channel); - led_enc = led_init_encoder(); + led_init_encoder(); led_setRGB(0, 0, 0); } @@ -75,7 +129,7 @@ void led_init(void) void led_deinit(void) { rmt_del_channel(led_rmt_channel); - rmt_del_encoder(led_enc); + rmt_del_encoder(&led_enc.base); } void led_setRGB(uint8_t r, uint8_t g, uint8_t b) @@ -86,7 +140,7 @@ void led_setRGB(uint8_t r, uint8_t g, uint8_t b) uint8_t pixel[] = {g, r, b}; rmt_enable(led_rmt_channel); - rmt_transmit(led_rmt_channel, led_enc->bytes_encoder, pixel, 3, &tx_conf); + rmt_transmit(led_rmt_channel, &(led_enc.base), pixel, 3, &tx_conf); rmt_tx_wait_all_done(led_rmt_channel, -1); rmt_disable(led_rmt_channel); } diff --git a/rx_esp32/src/utils.c b/rx_esp32/src/utils.c index 754be09..ff43318 100644 --- a/rx_esp32/src/utils.c +++ b/rx_esp32/src/utils.c @@ -26,7 +26,7 @@ char* getNextArg(char* args, const char separator) || *(args + step) == '\r' || *(args + step) == '\0' ) - { + { // end of line end = 2; } } @@ -39,21 +39,26 @@ char* getNextArg(char* args, const char separator) if (end == 1) { // argument separator found - end = 0; // find first char of argument - while (end == 0) + while (end == 1) { if (step < 255) { - step++; - if ( - *(args + step) != separator - && *(args + step) != '\n' + if (*(args + step) != separator) + { // found + end = 10; + } + else if ( + *(args + step) != '\n' && *(args + step) != '\r' && *(args + step) != '\0' ) + { // end of line + end = 11; + } + else { - end = 1; + step++; } } else @@ -62,7 +67,7 @@ char* getNextArg(char* args, const char separator) } } - if (end == 1) + if (end == 10) { // start of next argument found return args + step; } diff --git a/rx_esp32/test/README b/rx_esp32/test/README deleted file mode 100644 index 9b1e87b..0000000 --- a/rx_esp32/test/README +++ /dev/null @@ -1,11 +0,0 @@ - -This directory is intended for PlatformIO Test Runner and project tests. - -Unit Testing is a software testing method by which individual units of -source code, sets of one or more MCU program modules together with associated -control data, usage procedures, and operating procedures, are tested to -determine whether they are fit for use. Unit testing finds problems early -in the development cycle. - -More information about PlatformIO Unit Testing: -- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html