esp32: add leds sine fade helper
authorAndy Green <andy@warmcat.com>
Sun, 7 May 2017 05:24:48 +0000 (13:24 +0800)
committerAndy Green <andy@warmcat.com>
Tue, 9 May 2017 06:18:40 +0000 (14:18 +0800)
lib/libwebsockets.h
lib/lws-plat-esp32.c

index f673c1e..3baaf4e 100644 (file)
@@ -602,6 +602,10 @@ lws_esp_ota_get_boot_partition(void);
 extern int
 lws_esp32_get_image_info(const esp_partition_t *part, struct lws_esp32_image *i, char *json, int json_len);
 extern uint32_t lws_esp32_get_reboot_type(void);
+extern uint16_t lws_esp32_sine_interp(int n);
+
+/* required in external code by esp32 plat (may just return if no leds) */
+extern void lws_esp32_leds_timer_cb(TimerHandle_t th);
 #else
 typedef int lws_sockfd_type;
 typedef int lws_filefd_type;
index 1f58945..19536ce 100644 (file)
@@ -574,6 +574,8 @@ char *ERR_error_string(unsigned long e, char *buf)
 #include <tcpip_adapter.h>
 #include <esp_image_format.h>
 #include <esp_task_wdt.h>
+#include "soc/ledc_reg.h"
+#include "driver/ledc.h"
 
 struct lws_esp32 lws_esp32 = {
        .model = CONFIG_LWS_MODEL_NAME,
@@ -582,6 +584,7 @@ struct lws_esp32 lws_esp32 = {
 };
 
 static romfs_t lws_esp32_romfs;
+static TimerHandle_t leds_timer;
 
 struct esp32_file {
        const struct inode *i;
@@ -1002,6 +1005,20 @@ lws_esp32_init(struct lws_context_creation_info *info)
        char buf[512];
        size_t s;
        int n;
+       ledc_timer_config_t ledc_timer = {
+               .bit_num = LEDC_TIMER_13_BIT,
+               .freq_hz = 5000,
+               .speed_mode = LEDC_HIGH_SPEED_MODE,
+               .timer_num = LEDC_TIMER_0
+       };
+
+       ledc_timer_config(&ledc_timer);
+
+       /* user code needs to provide lws_esp32_leds_timer_cb */
+
+        leds_timer = xTimerCreate("lws_leds", pdMS_TO_TICKS(25), 1, NULL,
+                          (TimerCallbackFunction_t)lws_esp32_leds_timer_cb);
+        xTimerStart(leds_timer, 0);
 
        ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh));
        n = 0;
@@ -1052,3 +1069,39 @@ lws_esp32_init(struct lws_context_creation_info *info)
 
        return context;
 }
+
+static const uint16_t sineq16[] = {
+        0x0000, 0x0191, 0x031e, 0x04a4, 0x061e, 0x0789, 0x08e2, 0x0a24,
+        0x0b4e, 0x0c5c, 0x0d4b, 0x0e1a, 0x0ec6, 0x0f4d, 0x0faf, 0x0fea,
+};
+
+static uint16_t sine_lu(int n)
+{
+        switch ((n >> 4) & 3) {
+        case 0:
+                return 4096 + sineq16[n & 15];
+        case 1:
+                return 4096 + sineq16[15 - (n & 15)];
+        case 2:
+                return 4096 - sineq16[n & 15];
+        default:
+                return  4096 - sineq16[15 - (n & 15)];
+        }
+}
+
+/* useful for sine led fade patterns */
+
+uint16_t lws_esp32_sine_interp(int n)
+{
+        /*
+         * 2: quadrant
+         * 4: table entry in quadrant
+         * 4: interp (LSB)
+         *
+         * total 10 bits / 1024 steps per cycle
+         */
+
+        return (sine_lu(n >> 4) * (15 - (n & 15)) +
+                sine_lu((n >> 4) + 1) * (n & 15)) / 15;
+}
+