update led
This commit is contained in:
parent
858f1da0d8
commit
7184b101bf
2
rx_esp32/.gitignore
vendored
2
rx_esp32/.gitignore
vendored
@ -3,3 +3,5 @@
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
|
||||
build
|
||||
@ -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
|
||||
@ -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})
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -3,10 +3,13 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#include "led.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include "driver/rmt_tx.h"
|
||||
#include "driver/rmt_types.h"
|
||||
@ -15,12 +17,65 @@ typedef struct {
|
||||
} 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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user