diff --git a/include/libwebsockets.h b/include/libwebsockets.h index af28167c2..462658d06 100644 --- a/include/libwebsockets.h +++ b/include/libwebsockets.h @@ -612,10 +612,10 @@ struct lws; #include #include #include - #include - #include +#include +#include #ifdef __cplusplus } diff --git a/include/libwebsockets/lws-button.h b/include/libwebsockets/lws-button.h new file mode 100644 index 000000000..a1972c2a8 --- /dev/null +++ b/include/libwebsockets/lws-button.h @@ -0,0 +1,95 @@ +/* + * Generic button ops + * + * Copyright (C) 2019 - 2020 Andy Green + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Leverages the lws generic gpio pieces to bind gpio buttons to smd events + */ + +#if !defined(__LWS_BUTTON_H__) +#define __LWS_BUTTON_H__ + +typedef uint16_t lws_button_idx_t; + +typedef void (*lws_button_cb_t)(void *opaque, lws_button_idx_t idx, int state); + +/* + * This is the const part of the button controller, describing the static + * bindings to gpio, and lws_smd event name information + */ + +typedef struct lws_button_map { + _lws_plat_gpio_t gpio; + const char *smd_interaction_name; +} lws_button_map_t; + +typedef struct lws_button_controller { + const char *smd_bc_name; + const lws_gpio_ops_t *gpio_ops; + const lws_button_map_t *button_map; + lws_button_idx_t active_state_bitmap; + lws_button_idx_t message_on_down_bitmap; + lws_button_idx_t message_on_up_bitmap; + uint8_t count_buttons; +} lws_button_controller_t; + +struct lws_button_state; /* opaque */ + +/** + * lws_button_controller_create() - instantiate a button controller + * + * \param ctx: the lws_context + * \param controller: the static controller definition + * + * Instantiates a button controller from a static definition of the buttons + * and their smd names, and active levels, and binds it to a gpio implementation + */ + +LWS_VISIBLE LWS_EXTERN struct lws_button_state * +lws_button_controller_create(struct lws_context *ctx, + const lws_button_controller_t *controller); + +/** + * lws_button_controller_destroy() - destroys a button controller + * + * \param bcs: button controller state previously created + * + * Disables all buttons and then destroys and frees a previously created + * button controller. + */ + +LWS_VISIBLE LWS_EXTERN void +lws_button_controller_destroy(struct lws_button_state *bcs); + + +LWS_VISIBLE LWS_EXTERN lws_button_idx_t +lws_button_get_bit(struct lws_button_state *bcs, const char *name); + +/* + * lws_button_enable() - enable and disable buttons + */ + +LWS_VISIBLE LWS_EXTERN void +lws_button_enable(struct lws_button_state *bcs, + lws_button_idx_t _reset, lws_button_idx_t _set); + +#endif + diff --git a/include/libwebsockets/lws-display.h b/include/libwebsockets/lws-display.h index ff750aed4..8ac9e289c 100644 --- a/include/libwebsockets/lws-display.h +++ b/include/libwebsockets/lws-display.h @@ -96,7 +96,7 @@ typedef struct lws_diplay_state { * - off-only: set autodim to some ms and off_ms to 0 * - neither: set both autodim and off_ms to -1 */ -void +LWS_VISIBLE LWS_EXTERN void lws_display_state_init(lws_display_state_t *lds, struct lws_context *ctx, int autodim_ms, int off_ms, lws_display_brightness active, lws_display_brightness dim, const lws_display_t *disp); @@ -110,7 +110,7 @@ lws_display_state_init(lws_display_state_t *lds, struct lws_context *ctx, * * Adjusts the brightness gradually twoards the target at 20Hz */ -void +LWS_VISIBLE LWS_EXTERN void lws_display_state_set_brightness(lws_display_state_t *lds, lws_display_brightness target, lws_display_brightness step); @@ -123,7 +123,7 @@ lws_display_state_set_brightness(lws_display_state_t *lds, * Resets the auto-dim and auto-off timers and makes sure the display is on and * at the active brightness level */ -void +LWS_VISIBLE LWS_EXTERN void lws_display_state_active(lws_display_state_t *lds); /* @@ -134,7 +134,7 @@ lws_display_state_active(lws_display_state_t *lds); * Turns the display to least power mode or completely off if possible. * Disables the timers related to dimming and blanking. */ -void +LWS_VISIBLE LWS_EXTERN void lws_display_state_off(lws_display_state_t *lds); #endif diff --git a/include/libwebsockets/lws-i2c.h b/include/libwebsockets/lws-i2c.h index 5f8b6341a..3bd81ed37 100644 --- a/include/libwebsockets/lws-i2c.h +++ b/include/libwebsockets/lws-i2c.h @@ -44,10 +44,10 @@ typedef struct lws_i2c_ops { * These are implemented by calling the ops above, and so are generic */ -int +LWS_VISIBLE LWS_EXTERN int lws_i2c_command(const lws_i2c_ops_t *ctx, uint8_t ads7, uint8_t c); -int +LWS_VISIBLE LWS_EXTERN int lws_i2c_command_list(const lws_i2c_ops_t *ctx, uint8_t ads7, const uint8_t *buf, size_t len); diff --git a/include/libwebsockets/lws-led.h b/include/libwebsockets/lws-led.h new file mode 100644 index 000000000..015760f0a --- /dev/null +++ b/include/libwebsockets/lws-led.h @@ -0,0 +1,96 @@ +/* + * Generic LED controller ops + * + * Copyright (C) 2019 - 2020 Andy Green + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * This is like an abstract class for leds, a real implementation provides + * functions for the ops that use the underlying, eg, OS gpio arrangements. + */ + +#if !defined(__LWS_LED_H__) +#define __LWS_LED_H__ + +/* 0 is always OFF, for gpio, anything else is ON */ +typedef uint16_t lws_led_intensity_t; +typedef uint16_t lws_led_seq_phase_t; +#define LWS_LED_MAX_INTENSITY (0xffff) +#define LWS_LED_FRAME_RATE 20 +#define LWS_LED_FUNC_PHASE 1024 + +struct lws_led_state; /* opaque */ + +typedef lws_led_intensity_t (*lws_led_lookup_t)(int idx); + +typedef struct lws_led_sequence_def_t { + lws_led_lookup_t func; + lws_led_seq_phase_t ledphase_offset; + int ledphase_total; + int ms_full_phase; /* to compute rate */ +} lws_led_sequence_def_t; + +/* this should always be first in the subclassed implementation types */ + +typedef struct lws_led_ops { + void (*intensity)(const struct lws_led_ops *lo, int index, + lws_led_intensity_t inten); + int (*lookup)(const struct lws_led_ops *lo, const char *name); + struct lws_led_state * (*create)(const struct lws_led_ops *led_ops); + void (*destroy)(struct lws_led_state *); +} lws_led_ops_t; + +typedef struct lws_led_gpio_map { + const char *name; + _lws_plat_gpio_t gpio; + uint8_t active_level; +} lws_led_gpio_map_t; + +typedef struct lws_led_gpio_controller { + const lws_led_ops_t led_ops; + + const lws_gpio_ops_t *gpio_ops; + const lws_led_gpio_map_t *led_map; + uint8_t count_leds; +} lws_led_gpio_controller_t; + +/* ops */ + +LWS_VISIBLE LWS_EXTERN struct lws_led_state * +lws_led_gpio_create(const lws_led_ops_t *led_ops); + +LWS_VISIBLE LWS_EXTERN void +lws_led_gpio_destroy(struct lws_led_state *lcs); + +LWS_VISIBLE LWS_EXTERN void +lws_led_gpio_intensity(const struct lws_led_ops *lo, int index, lws_led_intensity_t inten); + +LWS_VISIBLE LWS_EXTERN int +lws_led_gpio_lookup(const struct lws_led_ops *lo, const char *name); + +#define lws_led_gpio_ops \ + { \ + .create = lws_led_gpio_create, \ + .destroy = lws_led_gpio_destroy, \ + .intensity = lws_led_gpio_intensity, \ + .lookup = lws_led_gpio_lookup, \ + } + +#endif + diff --git a/lib/drivers/CMakeLists.txt b/lib/drivers/CMakeLists.txt index 33a6b1935..192ca450d 100644 --- a/lib/drivers/CMakeLists.txt +++ b/lib/drivers/CMakeLists.txt @@ -3,6 +3,8 @@ list(APPEND SOURCES drivers/display/ssd1306-i2c.c drivers/i2c/lws-i2c.c drivers/i2c/bitbang/lws-bb-i2c.c + drivers/button/lws-button.c + drivers/led/led-gpio.c ) if (LWS_ESP_PLATFORM) diff --git a/lib/drivers/button/lws-button.c b/lib/drivers/button/lws-button.c new file mode 100644 index 000000000..ab1941491 --- /dev/null +++ b/lib/drivers/button/lws-button.c @@ -0,0 +1,168 @@ +/* + * Generic GPIO / irq buttons + * + * Copyright (C) 2019 - 2020 Andy Green + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "private-lib-core.h" + +#if defined(LWS_PLAT_FREERTOS) +#include +#endif + +/* + * This is the opaque, allocated, non-const, dynamic footprint of the + * button controller + */ + +typedef struct lws_button_state { +#if defined(LWS_PLAT_FREERTOS) + TimerHandle_t timer; +#endif + const lws_button_controller_t *controller; + struct lws_context *ctx; + lws_button_idx_t enable_bitmap; + lws_button_idx_t state_bitmap; +} lws_button_state_t; + +/* + * This is the bottom-half scheduled via a timer set in the ISR. From here + * we are allowed to hold mutexes etc. We are coming here because any button + * interrupt arrived, we have to try to figure out which events have happened. + */ + +#if defined(LWS_PLAT_FREERTOS) +static void +lws_button_bh(TimerHandle_t th) +{ + lws_button_state_t *bcs = pvTimerGetTimerID(th); + + lws_smd_msg_printf(bcs->ctx, LWSSMDCL_INTERACTION, + "{\"btn\":\"%s/%s\", \"s\":\"click\"}", + bcs->controller->smd_bc_name, + bcs->controller->button_map[0].smd_interaction_name); + +#if 0 + if (lws_esp32.button_is_down) + gpio_set_intr_type(GPIO_SW, GPIO_INTR_POSEDGE); + else + gpio_set_intr_type(GPIO_SW, GPIO_INTR_NEGEDGE); + + lws_esp32.button_is_down = gpio_get_level(GPIO_SW); + + lws_esp32_button(lws_esp32.button_is_down); +#endif +} +#endif + +struct lws_button_state * +lws_button_controller_create(struct lws_context *ctx, + const lws_button_controller_t *controller) +{ + lws_button_state_t *bcs = lws_zalloc(sizeof(lws_button_state_t), __func__); + + if (!bcs) + return NULL; + + bcs->controller = controller; + bcs->ctx = ctx; + +#if defined(LWS_PLAT_FREERTOS) + bcs->timer = xTimerCreate("bcst", 1, 0, bcs, + (TimerCallbackFunction_t)lws_button_bh); +#endif + + return bcs; +} + +void +lws_button_controller_destroy(struct lws_button_state *bcs) +{ + /* disable them all */ + lws_button_enable(bcs, 0, 0); + +#if defined(LWS_PLAT_FREERTOS) + xTimerDelete(&bcs->timer, 0); +#endif + + lws_free(bcs); +} + +/* + * This is happening in interrupt context, we have to schedule a bottom half to + * do the foreground lws_smd queueing, using, eg, a platform timer. + * + * All the buttons point here and use one timer per button controller. An + * interrupt here means, "something happened to one or more buttons" + */ + +void +lws_button_irq_cb_t(void *arg) +{ +#if defined(LWS_PLAT_FREERTOS) + lws_button_state_t *bcs = (lws_button_state_t *)arg; + + xTimerStart(bcs->timer, 0); +#endif +} + +lws_button_idx_t +lws_button_get_bit(struct lws_button_state *bcs, const char *name) +{ + const lws_button_controller_t *bc = bcs->controller; + int n; + + for (n = 0; n < bc->count_buttons; n++) + if (!strcmp(name, bc->button_map[n].smd_interaction_name)) + return 1 << n; + + return 0; /* not found */ +} + +void +lws_button_enable(lws_button_state_t *bcs, + lws_button_idx_t _reset, lws_button_idx_t _set) +{ + lws_button_idx_t u = (bcs->enable_bitmap & (~_reset)) | _set; + const lws_button_controller_t *bc = bcs->controller; + int n; + + for (n = 0; n < bcs->controller->count_buttons; n++) { + if (!(bcs->enable_bitmap & (1 << n)) && (u & (1 << n))) { + /* set as input with pullup or pulldown appropriately */ + bc->gpio_ops->mode(bc->button_map[n].gpio, + LWSGGPIO_FL_READ | + ((bc->active_state_bitmap & (1 << n)) ? + LWSGGPIO_FL_PULLDOWN : LWSGGPIO_FL_PULLUP)); + /* this one is becoming enabled */ + bc->gpio_ops->irq_mode(bc->button_map[n].gpio, + bc->active_state_bitmap & (1 << n) ? + LWSGGPIO_IRQ_RISING : + LWSGGPIO_IRQ_FALLING, + lws_button_irq_cb_t, bcs); + } + if ((bcs->enable_bitmap & (1 << n)) && !(u & (1 << n))) + /* this one is becoming disabled */ + bc->gpio_ops->irq_mode(bc->button_map[n].gpio, + LWSGGPIO_IRQ_NONE, NULL, NULL); + } + + bcs->enable_bitmap = u; +} diff --git a/lib/drivers/led/led-gpio.c b/lib/drivers/led/led-gpio.c new file mode 100644 index 000000000..11267f61d --- /dev/null +++ b/lib/drivers/led/led-gpio.c @@ -0,0 +1,150 @@ +/* + * Generic GPIO led + * + * Copyright (C) 2019 - 2020 Andy Green + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "private-lib-core.h" + +typedef struct lws_led_state +{ +#if defined(LWS_PLAT_FREERTOS) + TimerHandle_t timer; +#endif + lws_led_gpio_controller_t *controller; +} lws_led_state_t; + +#if defined(LWS_PLAT_FREERTOS) +static void +lws_led_timer_cb(TimerHandle_t th) +{ +// lws_led_state_t *lcs = pvTimerGetTimerID(th); +} +#endif + +struct lws_led_state * +lws_led_gpio_create(const lws_led_ops_t *led_ops) +{ + lws_led_state_t *lcs = lws_zalloc(sizeof(lws_led_state_t), __func__); + lws_led_gpio_controller_t *lgc = (lws_led_gpio_controller_t *)led_ops; + int n; + + if (!lcs) + return NULL; + + lcs->controller = lgc; + +#if defined(LWS_PLAT_FREERTOS) + lcs->timer = xTimerCreate("leds", 1, 0, lcs, + (TimerCallbackFunction_t)lws_led_timer_cb); +#endif + + for (n = 0; n < lgc->count_leds; n++) { + lgc->gpio_ops->mode(lgc->led_map[n].gpio, LWSGGPIO_FL_WRITE); + lgc->gpio_ops->set(lgc->led_map[n].gpio, + !lgc->led_map[n].active_level); + } + + return lcs; +} + +void +lws_led_gpio_destroy(struct lws_led_state *lcs) +{ +#if defined(LWS_PLAT_FREERTOS) + xTimerDelete(&lcs->timer, 0); +#endif + lws_free(lcs); +} + +void +lws_led_gpio_intensity(const struct lws_led_ops *lo, int idx, lws_led_intensity_t inten) +{ + const lws_led_gpio_controller_t *lgc = (lws_led_gpio_controller_t *)lo; + const lws_led_gpio_map_t *map = &lgc->led_map[idx]; + + lgc->gpio_ops->set(map->gpio, (!!map->active_level) ^ !inten); + +// ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, inten); +// ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0); +} + + +int +lws_led_gpio_lookup(const struct lws_led_ops *lo, const char *name) +{ + const lws_led_gpio_controller_t *lgc = (lws_led_gpio_controller_t *)lo; + int n; + + for (n = 0; n < lgc->count_leds; n++) + if (!strcmp(name, lgc->led_map[n].name)) + return n; + + return -1; +} + +static const lws_led_intensity_t sineq16[] = { + 0x0000, 0x0191, 0x031e, 0x04a4, 0x061e, 0x0789, 0x08e2, 0x0a24, + 0x0b4e, 0x0c5c, 0x0d4b, 0x0e1a, 0x0ec6, 0x0f4d, 0x0faf, 0x0fea, +}; + +static lws_led_intensity_t sine_lu(int n) +{ + switch ((n >> 4) & 3) { + case 1: + return 4096 + sineq16[n & 15]; + case 2: + return 4096 + sineq16[15 - (n & 15)]; + case 3: + return 4096 - sineq16[n & 15]; + default: + return 4096 - sineq16[15 - (n & 15)]; + } +} + +/* useful for sine led fade patterns */ + +lws_led_intensity_t lws_led_func_sine(int n) +{ + /* + * 2: quadrant + * 4: table entry in quadrant + * 4: interp (LSB) + * + * total 10 bits / 1024 steps per cycle + * + * + 0: 0 + * + 256: 4096 + * + 512: 8192 + * + 768: 4096 + * +1023: 0 + */ + + return (sine_lu(n >> 4) * (15 - (n & 15)) + + sine_lu((n >> 4) + 1) * (n & 15)) / 15; +} + +const lws_led_sequence_def_t lws_ledseq_sine_wipe = { + .func = lws_led_func_sine, + .ledphase_offset = 0, /* already at 0 amp at 0 phase */ + .ledphase_total = 512, /* 180 degree phase ./^ */ + .ms_full_phase = 1000, /* ie, 500ms for 180 degree */ +}; + diff --git a/minimal-examples/embedded/lws-minimal-esp32/main/lws-minimal-esp32.c b/minimal-examples/embedded/lws-minimal-esp32/main/lws-minimal-esp32.c index da6a672ed..7dd425960 100644 --- a/minimal-examples/embedded/lws-minimal-esp32/main/lws-minimal-esp32.c +++ b/minimal-examples/embedded/lws-minimal-esp32/main/lws-minimal-esp32.c @@ -28,8 +28,13 @@ struct lws_context *context; lws_sorted_usec_list_t sul; lws_display_state_t lds; +struct lws_led_state *lls; int interrupted; +/* + * Hook up bitbang i2c, display driver and display + */ + static void esp32_i2c_delay(void) { @@ -37,29 +42,90 @@ esp32_i2c_delay(void) } static const lws_bb_i2c_t li2c = { - .bb_ops = lws_bb_i2c_ops, - .scl = GPIO_NUM_15, - .sda = GPIO_NUM_4, - .gpio = &lws_gpio_plat, - .delay = esp32_i2c_delay + .bb_ops = lws_bb_i2c_ops, + .scl = GPIO_NUM_15, + .sda = GPIO_NUM_4, + .gpio = &lws_gpio_plat, + .delay = esp32_i2c_delay }; static const lws_display_ssd1306_t disp = { .disp = { lws_display_ssd1306_ops, - .w = 128, - .h = 64 + .w = 128, + .h = 64 }, - .i2c = (lws_i2c_ops_t *)&li2c, - .gpio = &lws_gpio_plat, - .reset_gpio = GPIO_NUM_16, - .i2c7_address = SSD1306_I2C7_ADS1 + .i2c = (lws_i2c_ops_t *)&li2c, + .gpio = &lws_gpio_plat, + .reset_gpio = GPIO_NUM_16, + .i2c7_address = SSD1306_I2C7_ADS1 +}; + +/* + * Button controller + */ + +static const lws_button_map_t bcm[] = { + { + .gpio = GPIO_NUM_0, + .smd_interaction_name = "user" + }, +}; + +static const lws_button_controller_t bc = { + .smd_bc_name = "bc", + .gpio_ops = &lws_gpio_plat, + .button_map = &bcm[0], + .active_state_bitmap = 0, + .message_on_down_bitmap = (1 << 0), + .message_on_up_bitmap = 0, + .count_buttons = LWS_ARRAY_SIZE(bcm) +}; + +/* + * led controller + */ + +static const lws_led_gpio_map_t lgm[] = { + { + .name = "alert", + .gpio = GPIO_NUM_25, + .active_level = 1, + }, +}; + +static const lws_led_gpio_controller_t lgc = { + .led_ops = lws_led_gpio_ops, + .gpio_ops = &lws_gpio_plat, + .led_map = &lgm[0], + .count_leds = LWS_ARRAY_SIZE(lgm) }; static const uint8_t img[] = { #include "../banded-img.h" }; +static uint8_t flip; + +static int +smd_cb(void *opaque, lws_smd_class_t _class, lws_usec_t timestamp, void *buf, + size_t len) +{ + flip = flip ^ 1; + lgc.led_ops.intensity(&lgc.led_ops, + lgc.led_ops.lookup(&lgc.led_ops, "alert"), flip); + + lwsl_hexdump_notice(buf, len); + + /* + * Any kind of user interaction brings the display back up and resets + * the dimming and blanking timers + */ + lws_display_state_active(&lds); + + return 0; +} + static void sul_cb(lws_sorted_usec_list_t *sul) { @@ -72,6 +138,7 @@ app_main(void) { wifi_init_config_t wic = WIFI_INIT_CONFIG_DEFAULT(); struct lws_context_creation_info info; + struct lws_button_state *bcs; int n = 0; lws_set_log_level(15, NULL); @@ -90,12 +157,26 @@ app_main(void) info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; info.port = CONTEXT_PORT_NO_LISTEN; + info.early_smd_cb = smd_cb; + info.early_smd_class_filter = LWSSMDCL_INTERACTION; context = lws_create_context(&info); if (!context) { lwsl_err("lws init failed\n"); return; } + lls = lgc.led_ops.create(&lgc.led_ops); + if (!lls) { + lwsl_err("%s: could not create led\n", __func__); + goto spin; + } + + bcs = lws_button_controller_create(context, &bc); + if (!bcs) { + lwsl_err("%s: could not create buttons\n", __func__); + goto spin; + } + /* * Show the lws logo on the display */ @@ -104,6 +185,8 @@ app_main(void) lws_display_state_active(&lds); disp.disp.blit(lds.disp, img, 0, 0, 128, 64); + lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user")); + /* * We say the test succeeded if we survive 3s around the event loop */ diff --git a/minimal-examples/embedded/lws-minimal-esp32/sdkconfig b/minimal-examples/embedded/lws-minimal-esp32/sdkconfig index a90f41ca1..6ed73d939 100644 --- a/minimal-examples/embedded/lws-minimal-esp32/sdkconfig +++ b/minimal-examples/embedded/lws-minimal-esp32/sdkconfig @@ -221,6 +221,7 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP-TLS # CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set # CONFIG_ESP_TLS_SERVER is not set # CONFIG_ESP_TLS_PSK_VERIFICATION is not set # end of ESP-TLS @@ -298,9 +299,9 @@ CONFIG_ADC_CAL_LUT_ENABLE=y # CONFIG_ESP_ERR_TO_NAME_LOOKUP=y CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=6584 +CONFIG_ESP_IPC_TASK_STACK_SIZE=3024 CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 CONFIG_ESP_CONSOLE_UART_DEFAULT=y @@ -408,7 +409,7 @@ CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y # High resolution timer (esp_timer) # # CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_TASK_STACK_SIZE=6584 # CONFIG_ESP_TIMER_IMPL_FRC2 is not set CONFIG_ESP_TIMER_IMPL_TG0_LAC=y # end of High resolution timer (esp_timer) @@ -537,7 +538,7 @@ CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 # CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION is not set CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 -CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=5048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set @@ -692,6 +693,7 @@ CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set # CONFIG_MBEDTLS_DEBUG is not set # @@ -709,8 +711,12 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_HARDWARE_MPI=y CONFIG_MBEDTLS_HARDWARE_SHA=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set # CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set @@ -722,11 +728,7 @@ CONFIG_MBEDTLS_TLS_ENABLED=y # # TLS Key Exchange Methods # -CONFIG_MBEDTLS_PSK_MODES=y -CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y +# CONFIG_MBEDTLS_PSK_MODES is not set CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y @@ -741,7 +743,7 @@ CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y @@ -791,6 +793,8 @@ CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y # CONFIG_MBEDTLS_POLY1305_C is not set # CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set # CONFIG_MBEDTLS_SECURITY_RISKS is not set # end of mbedTLS @@ -799,6 +803,7 @@ CONFIG_MBEDTLS_ECP_NIST_OPTIM=y # CONFIG_MDNS_MAX_SERVICES=10 CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_TASK_STACK_SIZE=4096 # CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set CONFIG_MDNS_TASK_AFFINITY_CPU0=y # CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set @@ -980,6 +985,7 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_DEBUG_PRINT is not set # CONFIG_WPA_TESTING_OPTIONS is not set # CONFIG_WPA_TLS_V12 is not set +# CONFIG_WPA_WPS_WARS is not set # end of Supplicant # end of Component config @@ -1059,9 +1065,9 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y # CONFIG_NO_BLOBS is not set # CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=3584 -CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=4304 +CONFIG_MAIN_TASK_STACK_SIZE=6584 +CONFIG_IPC_TASK_STACK_SIZE=3024 CONFIG_CONSOLE_UART_DEFAULT=y # CONFIG_CONSOLE_UART_CUSTOM is not set # CONFIG_CONSOLE_UART_NONE is not set @@ -1084,7 +1090,7 @@ CONFIG_POST_EVENTS_FROM_IRAM_ISR=y CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y # CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set # CONFIG_ESP32S2_PANIC_GDBSTUB is not set -CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_TIMER_TASK_STACK_SIZE=6584 CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 CONFIG_MB_QUEUE_LENGTH=20 @@ -1101,7 +1107,7 @@ CONFIG_MB_TIMER_GROUP=0 CONFIG_MB_TIMER_INDEX=0 # CONFIG_SUPPORT_STATIC_ALLOCATION is not set CONFIG_TIMER_TASK_PRIORITY=1 -CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_TASK_STACK_DEPTH=5048 CONFIG_TIMER_QUEUE_LENGTH=10 # CONFIG_L2_TO_L3_COPY is not set # CONFIG_USE_ONLY_LWIP_SELECT is not set @@ -1143,3 +1149,4 @@ CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 # End of deprecated options +