Skip to content

Improve neopixel on ESP #8920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions docs/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ Read-only characteristic that returns the UTF-8 encoded version string.
If the keys `CIRCUITPY_WIFI_SSID` and `CIRCUITPY_WIFI_PASSWORD` are set in `settings.toml`,
CircuitPython will automatically connect to the given Wi-Fi network on boot and upon reload.

If `CIRCUITPY_WEB_API_PASSWORD` is also set, the web workflow will also start.
The web workflow will only be enabled if the Wi-Fi connection succeeds upon boot.
If `CIRCUITPY_WEB_API_PASSWORD` is set, MDNS and the http server for the web workflow will also start.

The webserver is on port 80 unless overridden by `CIRCUITPY_WEB_API_PORT`. It also enables MDNS.
The name of the board as advertised to the network can be overridden by `CIRCUITPY_WEB_INSTANCE_NAME`.
Expand All @@ -84,7 +83,7 @@ Here is an example `/settings.toml`:
CIRCUITPY_WIFI_SSID="scottswifi"
CIRCUITPY_WIFI_PASSWORD="secretpassword"

# To enable the the webserver. Change this too!
# To enable the web workflow. Change this too!
# Leave the User field blank in the browser.
CIRCUITPY_WEB_API_PASSWORD="passw0rd"

Expand Down
22 changes: 18 additions & 4 deletions ports/espressif/common-hal/neopixel_write/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,20 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
.clk_src = RMT_CLK_SRC_DEFAULT,
.resolution_hz = 40000000,
.trans_queue_depth = 1,
.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL,
};

// Greedily try and grab as much RMT memory as we can. The more we get, the
// smoother the output will be because we'll trigger fewer interrupts. We'll
// give it all back once we're done.
rmt_channel_handle_t channel;
CHECK_ESP_RESULT(rmt_new_tx_channel(&config, &channel));
esp_err_t result = ESP_ERR_NOT_FOUND;
// If no other channels are in use, we can use all of the RMT RAM including the RX channels.
config.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * SOC_RMT_CHANNELS_PER_GROUP;
while (result == ESP_ERR_NOT_FOUND && config.mem_block_symbols > 0) {
result = rmt_new_tx_channel(&config, &channel);
config.mem_block_symbols -= SOC_RMT_MEM_WORDS_PER_CHANNEL;
}
CHECK_ESP_RESULT(result);

size_t ns_per_tick = 1e9 / 40000000;
uint16_t ws2812_t0h_ticks = WS2812_T0H_NS / ns_per_tick;
Expand Down Expand Up @@ -97,7 +107,11 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
}
};
rmt_encoder_handle_t encoder;
CHECK_ESP_RESULT(rmt_new_bytes_encoder(&encoder_config, &encoder));
result = rmt_new_bytes_encoder(&encoder_config, &encoder);
if (result != ESP_OK) {
rmt_del_channel(channel);
return;
}

// Wait to make sure we don't append onto the last transmission. This should only be a tick or
// two.
Expand All @@ -111,7 +125,7 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
.loop_count = 0,
.flags.eot_level = 0
};
esp_err_t result = rmt_transmit(channel, encoder, pixels, (size_t)numBytes, &transmit_config);
result = rmt_transmit(channel, encoder, pixels, (size_t)numBytes, &transmit_config);
if (result != ESP_OK) {
rmt_del_encoder(encoder);
rmt_disable(channel);
Expand Down
1 change: 1 addition & 0 deletions ports/espressif/esp-idf-config/sdkconfig-esp32.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ CONFIG_PCNT_CTRL_FUNC_IN_IRAM=y
# ESP System Settings
#
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1=y
# end of ESP System Settings

#
Expand Down
4 changes: 2 additions & 2 deletions supervisor/shared/web_workflow/web_workflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ void supervisor_web_workflow_status(void) {
}
#endif

bool supervisor_start_web_workflow(bool reload) {
bool supervisor_start_web_workflow(void) {
#if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI && CIRCUITPY_OS_GETENV

char ssid[33];
Expand Down Expand Up @@ -310,7 +310,7 @@ bool supervisor_start_web_workflow(bool reload) {

bool initialized = pool.base.type == &socketpool_socketpool_type;

if (!initialized && !reload) {
if (!initialized) {
result = common_hal_os_getenv_str("CIRCUITPY_WEB_INSTANCE_NAME", web_instance_name, sizeof(web_instance_name));
if (result != GETENV_OK || web_instance_name[0] == '\0') {
strcpy(web_instance_name, MICROPY_HW_BOARD_NAME);
Expand Down
2 changes: 1 addition & 1 deletion supervisor/shared/web_workflow/web_workflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
void supervisor_web_workflow_background(void *data);
bool supervisor_web_workflow_status_dirty(void);
void supervisor_web_workflow_status(void);
bool supervisor_start_web_workflow(bool);
bool supervisor_start_web_workflow(void);
void supervisor_stop_web_workflow(void);

// Share the MDNS object with user code.
Expand Down
4 changes: 2 additions & 2 deletions supervisor/shared/workflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ void supervisor_workflow_reset(void) {
#endif

#if CIRCUITPY_WEB_WORKFLOW
bool result = supervisor_start_web_workflow(true);
bool result = supervisor_start_web_workflow();
if (workflow_background_cb.fun) {
if (result) {
supervisor_workflow_request_background();
Expand Down Expand Up @@ -108,7 +108,7 @@ void supervisor_workflow_start(void) {
#endif

#if CIRCUITPY_WEB_WORKFLOW
if (supervisor_start_web_workflow(false)) {
if (supervisor_start_web_workflow()) {
// Enable background callbacks if web_workflow startup successful
memset(&workflow_background_cb, 0, sizeof(workflow_background_cb));
workflow_background_cb.fun = supervisor_web_workflow_background;
Expand Down