my friend and i are on a project right now and are quite stuck on coding some LED.
We are total beginner and help is much appreciated.
This is the following excercise:
Finish the implementation of the ws2812b_init function. In this function, return all errors to the caller instead of aborting. At the end of the function, we call ws2812b_clear() and ws2812b_show(). Add the following before that:
Save important config values for later use
Allocate heap memory for the LED pixel buffer (stores the color data for each LED as 3 bytes in GBR order), as well as the RMT symbol buffer (the RMT peripheral accesses this buffer). Use standard malloc and check for allocation errors! Hint: There are some useful macros at the top that may help you...
Create an RMT TX channel (rmt_new_tx_channel) using the provided RMT config
Create a "copy encoder" (rmt_new_copy_encoder). The encoder copies our RMT symbols as-is to the RMT peripheral
Enable the created RMT TX channel (rmt_enable). This sets up some stuff internally
We are currently on the 4th point of the excercises. Create a "copy encoder" (rmt_new_copy_encoder). The encoder copies our RMT symbols as-is to the RMT peripheral
The method rmt_new_copy_encoder takes a rmt_copy_encoder_config_t and the rmt_encoder_handle_t.
The thing is that no where is written if we should create such configuration and we also have put the handle on Null.
We dont know any further. D:
This is the code we have worked on up until now.
- #include "include/ws2812b.h"
- #include <driver/rmt_tx.h>
- #include <esp_check.h>
- #include <esp_err.h>
- #include <esp_log.h>
- #include <string.h>
- static const char *TAG = "WS2812B";
- /**** CONSTANTS ****/
- #define PIXEL_BYTES (pixel_count * 3)
- #define SYMBOL_BYTES (PIXEL_BYTES * 8 * sizeof(rmt_symbol_word_t)) // 8 bits per byte -> 8 symbols per byte
- /**** TIMINGS ****/
- // See https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf
- // Timings are given in 0.1us (we use 10Mhz resolution, round if necessary)
- // TODO 2.2: Find out the correct timings and replace the '0's
- #define T0H_TIME (4) // 0 bit high time
- #define T0L_TIME (9) // 0 bit low time
- #define T1H_TIME (8) // 1 bit high time
- #define T1L_TIME (5) // 1 bit low time
- #define RST_TIME (500) // reset time
- /**** GLOBAL STATE ****/
- static size_t pixel_count;
- static uint8_t *pixel_buffer;
- static rmt_symbol_word_t *symbol_buffer;
- // TODO 2.3: What else do you need here?
- static gpio_num_t data_gpio_num;
- static rmt_channel_handle_t rmt_channel = NULL;
- static rmt_encoder_handle_t copy_encoder = NULL;
- esp_err_t ws2812b_init(const ws2812b_config_t *config) {
- esp_err_t ret = ESP_OK;
- ESP_LOGI(TAG, "Initializing WS2812B driver...");
- //ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "WS2812B driver not implemented yet. REMOVE ME!");
- // TODO 2.3: Save necessary config values in global state if you need them later and initialize everything
- pixel_count = config->pixel_count;
- data_gpio_num = config->data_gpio_num;
- //allocation of pixel buffer mem
- pixel_buffer = (uint8_t *)malloc(PIXEL_BYTES); //GBR
- if (pixel_buffer == NULL) {
- ESP_LOGE(TAG, "Failed to allocate memory");
- return ESP_ERR_NO_MEM; //no memory
- }
- //allocation of RMT Symbol buffer mem
- symbol_buffer = (rmt_symbol_word_t *)malloc(SYMBOL_BYTES);
- if (symbol_buffer == NULL) {
- free(pixel_buffer);
- ESP_LOGE(TAG, "Failed to allocate memory");
- return ESP_ERR_NO_MEM; //no mem
- }
- // RMT-related use this RMT channel config
- rmt_tx_channel_config_t rmt_config = {
- .gpio_num = config->data_gpio_num,
- .clk_src = RMT_CLK_SRC_DEFAULT,
- .resolution_hz = 10000000, // 10MHz resolution, 1 tick = 0.1us (timings need to be rounded but this is ok)
- .mem_block_symbols = 64, // increasing this in steps of 64 can reduce flickering
- .trans_queue_depth = 4, // maximum pending background transfers, 4 is a good default value
- // we leave everything else at default values
- };
- //create RMT channel with channel config
- esp_err_t err = rmt_new_tx_channel(&rmt_config,& rmt_channel);
- if (err!= ESP_OK) {
- ESP_LOGE(TAG, "Failed to create new rmt tx channel D:");
- free(pixel_buffer);
- free(symbol_buffer);
- return err;
- }
- //create copy encoder
- err = rmt_new_copy_encoder(true, ©_encoder);
- if(err!= ESP_OK){
- }
- //enable TX
- // turn LEDs off in case they were on previously
- ws2812b_clear();
- ws2812b_show();
- ESP_LOGI(TAG, "WS2812B driver initialized");
- return ESP_OK;
- err:
- // TODO 2.3: Clean up everything that you've already initialized.
- // Hint: Do you already have this functionality somewhere?
- return ret;
- }