diff --git a/code/.project b/code/.project
index 1514a30..06fb76d 100644
--- a/code/.project
+++ b/code/.project
@@ -968,11 +968,6 @@
1
/home/matthias/esp/esp-idf/components/vfs/vfs_uart.c
-
- build/ide/esp_idf_components/vfs/vfs_usb_serial_jtag.c
- 1
- /home/matthias/esp/esp-idf/components/vfs/vfs_usb_serial_jtag.c
-
build/ide/esp_idf_components/wear_levelling/Partition.cpp
1
diff --git a/code/main/CMakeLists.txt b/code/main/CMakeLists.txt
index eeaffee..4970044 100644
--- a/code/main/CMakeLists.txt
+++ b/code/main/CMakeLists.txt
@@ -7,6 +7,7 @@ idf_component_register(
"src/gpio.cpp"
"src/wifi.cpp"
"src/logger.cpp"
+ "src/led_strip_encoder.c"
INCLUDE_DIRS # optional, add here public include directories
"inc"
PRIV_INCLUDE_DIRS # optional, add here private include directories
diff --git a/code/main/inc/led_strip_encoder.h b/code/main/inc/led_strip_encoder.h
new file mode 100644
index 0000000..db5ef07
--- /dev/null
+++ b/code/main/inc/led_strip_encoder.h
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#pragma once
+
+#include
+#include "driver/rmt_encoder.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Type of led strip encoder configuration
+ */
+typedef struct {
+ uint32_t resolution; /*!< Encoder resolution, in Hz */
+} led_strip_encoder_config_t;
+
+/**
+ * @brief Create RMT encoder for encoding LED strip pixels into RMT symbols
+ *
+ * @param[in] config Encoder configuration
+ * @param[out] ret_encoder Returned encoder handle
+ * @return
+ * - ESP_ERR_INVALID_ARG for any invalid arguments
+ * - ESP_ERR_NO_MEM out of memory when creating led strip encoder
+ * - ESP_OK if creating encoder successfully
+ */
+esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/code/main/inc/logger.h b/code/main/inc/logger.h
index 5429571..8ce00e4 100644
--- a/code/main/inc/logger.h
+++ b/code/main/inc/logger.h
@@ -56,21 +56,28 @@
* \memberof Logger
*/
#define LOGGER_ERROR(...) \
- Logger_log(__FILE__, __func__, __LINE__, LOGTYPE_ERROR, ##__VA_ARGS__)
+ Logger::Logger_log(__FILE__, __func__, __LINE__, LOGTYPE_ERROR, ##__VA_ARGS__)
+
+/**
+ * Logs a success
+ * \memberof Logger
+ */
+#define LOGGER_SUCCESS(...) \
+ Logger::Logger_log(__FILE__, __func__, __LINE__, LOGTYPE_SUCCESS, ##__VA_ARGS__)
/**
* Logs an error
* \memberof Logger
*/
#define LOGGER_WARNING(...) \
- Logger_log(__FILE__, __func__, __LINE__, LOGTYPE_WARNING, ##__VA_ARGS__)
+ Logger::Logger_log(__FILE__, __func__, __LINE__, LOGTYPE_WARNING, ##__VA_ARGS__)
/**
* Logs an error
* \memberof Logger
*/
#define LOGGER_INFO(...) \
- Logger_log(__FILE__, __func__, __LINE__, LOGTYPE_INFO, ##__VA_ARGS__)
+ Logger::Logger_log(__FILE__, __func__, __LINE__, LOGTYPE_INFO, ##__VA_ARGS__)
/**
* Logs an error
@@ -84,42 +91,49 @@
* \memberof Logger
*/
#define LOGGER_PRINT(...) \
- Logger_log("", "", 0, LOGTYPE_PRINT, ##__VA_ARGS__)
+ Logger::Logger_log("", "", 0, LOGTYPE_PRINT, ##__VA_ARGS__)
/**
* Logs an error
* \memberof Logger
*/
#define LOGGER_ERROR_ISR(...) \
- Logger_logISR(__FILE__, __func__, __LINE__, LOGTYPE_ERROR, ##__VA_ARGS__)
+ Logger::Logger_logISR(__FILE__, __func__, __LINE__, LOGTYPE_ERROR, ##__VA_ARGS__)
+
+/**
+ * Logs a success
+ * \memberof Logger
+ */
+#define LOGGER_SUCCESS_ISR(...) \
+ Logger::Logger_logISR(__FILE__, __func__, __LINE__, LOGTYPE_ERROR, ##__VA_ARGS__)
/**
* Logs an error
* \memberof Logger
*/
#define LOGGER_WARNING_ISR(...) \
- Logger_logISR(__FILE__, __func__, __LINE__, LOGTYPE_WARNING, ##__VA_ARGS__)
+ Logger::Logger_logISR(__FILE__, __func__, __LINE__, LOGTYPE_WARNING, ##__VA_ARGS__)
/**
* Logs an error
* \memberof Logger
*/
#define LOGGER_INFO_ISR(...) \
- Logger_logISR(__FILE__, __func__, __LINE__, LOGTYPE_INFO, ##__VA_ARGS__)
+ Logger::Logger_logISR(__FILE__, __func__, __LINE__, LOGTYPE_INFO, ##__VA_ARGS__)
/**
* Logs an error
* \memberof Logger
*/
#define LOGGER_DEBUG_ISR(a, ...) \
- Logger_logISR(a, __FILE__, __func__, __LINE__, LOGTYPE_DEBUG, ##__VA_ARGS__)
+ Logger::Logger_logISR(a, __FILE__, __func__, __LINE__, LOGTYPE_DEBUG, ##__VA_ARGS__)
/**
* Logs an error
* \memberof Logger
*/
#define LOGGER_PRINT_ISR(a, ...) \
- Logger_logISR(a, "", "", 0, LOGTYPE_PRINT, ##__VA_ARGS__)
+ Logger::Logger_logISR(a, "", "", 0, LOGTYPE_PRINT, ##__VA_ARGS__)
// --------------------------------------------------------------------------------------------------------------------
// Type definitions.
diff --git a/code/main/main.cpp b/code/main/main.cpp
index 2deb336..f1d2911 100644
--- a/code/main/main.cpp
+++ b/code/main/main.cpp
@@ -5,15 +5,18 @@
#include "esp_log.h"
#include "esp_sntp.h"
#include "esp_wifi.h"
+#include "time.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
-#include "inc/gpio.h"
+#include "driver/rmt_tx.h"
#include "driver/uart_select.h"
-#include "inc/wifi.h"
+#include "inc/gpio.h"
+#include "inc/led_strip_encoder.h"
#include "inc/logger.h"
+#include "inc/wifi.h"
static const uart_port_t uartPort = UART_NUM_0;
static TaskHandle_t devTaskHandle = NULL;
@@ -22,6 +25,8 @@ static GPIO gpio0(4, GPIO_DIRECTION_OUTPUT);
static GPIO gpio1(18, GPIO_DIRECTION_OUTPUT);
static time_t currentTime;
+#define RMT_LED_STRIP_RESOLUTION_HZ 10000000 // 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
+#define RMT_LED_STRIP_GPIO_NUM 8
extern "C" void app_main(void)
{
@@ -52,17 +57,54 @@ extern "C" void app_main(void)
ESP_ERROR_CHECK(uart_set_pin(uartPort, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
ESP_ERROR_CHECK(uart_driver_install(uartPort, 1024, 1024, 0, NULL, 0));
- uart_write_bytes(uartPort, "helloWorld", sizeof("helloworld"));
-
+ //--------------------------------------------
+ // LOGGER
+ //
Logger logger(10, uartPort);
- logger.Logger_log(__FILE__, __func__, __LINE__, LOGTYPE_DEBUG, "Hello World from the Logger himself");
LOGGER_DEBUG("YEAHAAA");
+
+ //--------------------------------------------
+ // RMT Channel
+ //
+ LOGGER_INFO("Create RMT TX channel");
+ rmt_channel_handle_t led_chan = NULL;
+ rmt_tx_channel_config_t tx_chan_config;
+ memset(&tx_chan_config, 0, sizeof(tx_chan_config));
+
+ tx_chan_config.clk_src = RMT_CLK_SRC_DEFAULT; // select source clock
+ tx_chan_config.gpio_num = RMT_LED_STRIP_GPIO_NUM;
+ tx_chan_config.mem_block_symbols = 64; // increase the block size can make the LED less flickering
+ tx_chan_config.resolution_hz = RMT_LED_STRIP_RESOLUTION_HZ;
+ tx_chan_config.trans_queue_depth = 4;
+
+ ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &led_chan));
+
+ LOGGER_INFO("Install led strip encoder");
+ rmt_encoder_handle_t led_encoder = NULL;
+ led_strip_encoder_config_t encoder_config;
+ memset(&encoder_config, 0, sizeof(encoder_config));
+ encoder_config.resolution = RMT_LED_STRIP_RESOLUTION_HZ;
+
+ ESP_ERROR_CHECK(rmt_new_led_strip_encoder(&encoder_config, &led_encoder));
+
+ LOGGER_INFO("Enable RMT TX channel");
+ ESP_ERROR_CHECK(rmt_enable(led_chan));
+
+ rmt_transmit_config_t tx_config;
+ memset(&tx_config, 0, sizeof(tx_config));
+ tx_config.loop_count = 0;
+
+
+
+
+
+
// Create the development task
if(xTaskCreate(devTask, "DevTask", 2048, NULL, 3, &devTaskHandle) != pdPASS)
{
- printf("Task not created");
+ LOGGER_ERROR("Task not created");
}
Wifi wifi;
@@ -75,6 +117,9 @@ extern "C" void app_main(void)
sntp_setservername(0, "pool.ntp.org");
sntp_init();
+
+ uint8_t led_strip_pixels[111 * 3];
+ int counter = 0;
while (true)
{
@@ -82,9 +127,24 @@ extern "C" void app_main(void)
time(¤tTime);
localtime_r(¤tTime, &tm);
- printf("%lld\n\r", currentTime);
- printf("%i:%i:%i\n\r", tm.tm_hour, tm.tm_min, tm.tm_sec);
- vTaskDelay(1000);
+ LOGGER_INFO("%lld\n\r", currentTime);
+ LOGGER_INFO("%i:%i:%i\n\r", tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ memset(&led_strip_pixels, 0, sizeof(led_strip_pixels));
+ led_strip_pixels[counter * 3 + 0] = 0x3F;
+ led_strip_pixels[counter * 3 + 1] = 0x3F;
+ led_strip_pixels[counter * 3 + 2] = 0x3F;
+
+ if (counter < 111)
+ {
+ counter++;
+ }
+ else
+ {
+ counter = 0;
+ }
+ rmt_transmit(led_chan, led_encoder, led_strip_pixels, sizeof(led_strip_pixels), &tx_config);
+ vTaskDelay(5);
}
}
@@ -100,6 +160,7 @@ static void devTask(void* parameters)
(void)gpio0.SetOutput((GPIO_Value_t)(counter % 2));
(void)gpio1.SetOutput((GPIO_Value_t)(counter % 7));
counter++;
+
vTaskDelay(100);
}
}
diff --git a/code/main/src/led_strip_encoder.c b/code/main/src/led_strip_encoder.c
new file mode 100644
index 0000000..aff7fee
--- /dev/null
+++ b/code/main/src/led_strip_encoder.c
@@ -0,0 +1,124 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "esp_check.h"
+#include "led_strip_encoder.h"
+
+static const char *TAG = "led_encoder";
+
+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_led_strip_encoder_t;
+
+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 = __containerof(encoder, rmt_led_strip_encoder_t, base);
+ rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder;
+ rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder;
+ 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 += bytes_encoder->encode(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 += copy_encoder->encode(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;
+}
+
+esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder)
+{
+ esp_err_t ret = ESP_OK;
+ rmt_led_strip_encoder_t *led_encoder = NULL;
+ ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
+ led_encoder = calloc(1, sizeof(rmt_led_strip_encoder_t));
+ ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder");
+ led_encoder->base.encode = rmt_encode_led_strip;
+ led_encoder->base.del = rmt_del_led_strip_encoder;
+ led_encoder->base.reset = rmt_led_strip_encoder_reset;
+ // different led strip might have its own timing requirements, following parameter is for WS2812
+ rmt_bytes_encoder_config_t bytes_encoder_config = {
+ .bit0 = {
+ .level0 = 1,
+ .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us
+ .level1 = 0,
+ .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us
+ },
+ .bit1 = {
+ .level0 = 1,
+ .duration0 = 0.9 * config->resolution / 1000000, // T1H=0.9us
+ .level1 = 0,
+ .duration1 = 0.3 * config->resolution / 1000000, // T1L=0.3us
+ },
+ .flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0
+ };
+ ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed");
+ rmt_copy_encoder_config_t copy_encoder_config = {};
+ ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed");
+
+ uint32_t reset_ticks = config->resolution / 1000000 * 50 / 2; // reset code duration defaults to 50us
+ led_encoder->reset_code = (rmt_symbol_word_t) {
+ .level0 = 0,
+ .duration0 = reset_ticks,
+ .level1 = 0,
+ .duration1 = reset_ticks,
+ };
+ *ret_encoder = &led_encoder->base;
+ return ESP_OK;
+err:
+ if (led_encoder) {
+ if (led_encoder->bytes_encoder) {
+ rmt_del_encoder(led_encoder->bytes_encoder);
+ }
+ if (led_encoder->copy_encoder) {
+ rmt_del_encoder(led_encoder->copy_encoder);
+ }
+ free(led_encoder);
+ }
+ return ret;
+}
diff --git a/code/main/src/logger.cpp b/code/main/src/logger.cpp
index 72626c9..0558193 100644
--- a/code/main/src/logger.cpp
+++ b/code/main/src/logger.cpp
@@ -219,6 +219,10 @@ void Logger::loggerTask(void* parameters)
{
vt100Prefix = "\033[31m";
}
+ else if(logQueueItem.logType == LOGTYPE_SUCCESS)
+ {
+ vt100Prefix = "\033[32m";
+ }
#endif
unsigned int seconds = 0;
@@ -229,6 +233,7 @@ void Logger::loggerTask(void* parameters)
vt100Prefix,
(logQueueItem.logType == LOGTYPE_DEBUG) ? "DBG" :
(logQueueItem.logType == LOGTYPE_INFO) ? "INF" :
+ (logQueueItem.logType == LOGTYPE_SUCCESS) ? "SCS" :
(logQueueItem.logType == LOGTYPE_WARNING) ? "WRN" : "ERR",
seconds,
logQueueItem.fileName,
diff --git a/code/main/src/wifi.cpp b/code/main/src/wifi.cpp
index cd4ccca..550a57f 100644
--- a/code/main/src/wifi.cpp
+++ b/code/main/src/wifi.cpp
@@ -22,6 +22,8 @@
#include "wifi.h"
+#include "logger.h"
+
// --------------------------------------------------------------------------------------------------------------------
// Constant and macro definitions
// --------------------------------------------------------------------------------------------------------------------
@@ -46,8 +48,10 @@
// --------------------------------------------------------------------------------------------------------------------
-static const char* ssid = "Kowalski";
-static const char* pass = "madagascar";
+//static const char* ssid = "Kowalski";
+//static const char* pass = "madagascar";
+static const char* ssid = "vbchaos";
+static const char* pass = "mijninternet";
// --------------------------------------------------------------------------------------------------------------------
// Function declarations
@@ -82,18 +86,18 @@ void Wifi::event_handler(void *arg, esp_event_base_t event_base, int32_t event_i
{
esp_wifi_connect();
s_retry_num++;
- ESP_LOGI(TAG, "retry to connect to the AP");
+ LOGGER_INFO("%s - retry to connect to the AP", TAG);
}
else
{
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
- ESP_LOGI(TAG, "connect to the AP fail");
+ LOGGER_ERROR("%S - connect to the AP fail", TAG);
}
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));
+ LOGGER_SUCCESS("%s - got ip: %d:%d:%d:%d", TAG, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
@@ -130,7 +134,7 @@ void Wifi::start_client(void)
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.");
+ LOGGER_INFO("%s - wifi_init_sta finished", TAG);
/* 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) */
@@ -144,15 +148,15 @@ void Wifi::start_client(void)
* happened. */
if (bits & WIFI_CONNECTED_BIT)
{
- ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", ssid, pass);
+ LOGGER_SUCCESS("%s - connected to ap SSID:%s password:%s", TAG, ssid, pass);
}
else if (bits & WIFI_FAIL_BIT)
{
- ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", ssid, pass);
+ LOGGER_ERROR("%s - Failed to connect to SSID:%s, password:%s", TAG, ssid, pass);
}
else
{
- ESP_LOGE(TAG, "UNEXPECTED EVENT");
+ LOGGER_ERROR("%s - UNEXPECTED EVENT", TAG);
}
}