|
@@ -1,70 +1,29 @@
|
|
|
+/*******************************************************************************
|
|
|
+ * WS2812 Driver for IdeasX
|
|
|
+ * Author: curiousmuch
|
|
|
+ * Description: LED driver for v0.3.X encoder
|
|
|
+ * Todo: Improve pulse mode to use less CPU cycles and fluidity of cycle.
|
|
|
+*******************************************************************************/
|
|
|
+
|
|
|
#include "hal/ws2812.h"
|
|
|
-#include "ets_sys.h"
|
|
|
-#include "osapi.h"
|
|
|
-#include "gpio.h"
|
|
|
-#include "math.h"
|
|
|
-
|
|
|
-#define LEDUPDATEDELAY 60
|
|
|
-
|
|
|
-// LOCAL const
|
|
|
-
|
|
|
-LOCAL uint8_t pulseBuffer[100] = { 127, 135, 143, 151, 159, 166, 174, 181, 188,
|
|
|
- 195, 202, 208, 214, 220, 225, 230, 235, 239,
|
|
|
- 242, 246, 248, 250, 252, 253, 254, 255, 254,
|
|
|
- 253, 252, 250, 248, 246, 242, 239, 235, 230,
|
|
|
- 225, 220, 214, 208, 202, 195, 188, 181, 174,
|
|
|
- 166, 159, 151, 143, 135, 127, 119, 111, 103,
|
|
|
- 95, 88, 80, 73, 66, 59, 52, 46, 40, 34, 29,
|
|
|
- 24, 19, 15, 12, 8, 6, 4, 2, 1, 0, 0, 0, 1, 2,
|
|
|
- 4, 6, 8, 12, 15, 19, 24, 29, 34, 40, 46, 52,
|
|
|
- 59, 66, 73, 80, 88, 95, 103, 111, 119};
|
|
|
-
|
|
|
-
|
|
|
-// LOCAL uint8_t pulseBuffer[100] = { 50, 53, 56, 59, 62, 65, 68, 71,
|
|
|
-// 74, 76, 79, 81, 84, 86, 88, 90,
|
|
|
-// 92, 93, 95, 96, 97, 98, 99, 99,
|
|
|
-// 99, 100, 99, 99, 99, 98, 97, 96,
|
|
|
-// 95, 93, 92, 90, 88, 86, 84, 81,
|
|
|
-// 79, 76, 74, 71, 68, 65, 62, 59,
|
|
|
-// 56, 53, 50, 46, 43, 40, 37, 34,
|
|
|
-// 31, 28, 25, 23, 20, 18, 15, 13,
|
|
|
-// 11, 9, 7, 6, 4, 3, 2, 1, 0, 0,
|
|
|
-// 0, 0, 0, 0, 0, 1, 2, 3, 4, 6,
|
|
|
-// 7, 9, 11, 13, 15, 18, 20, 23,
|
|
|
-// 25, 28, 31, 34, 37, 40, 43, 46};
|
|
|
-
|
|
|
-// uint8_t pulseBuffer[100] = {68, 75, 83, 90, 99, 107, 116, 126,
|
|
|
-// 135, 145, 155, 165, 175, 184, 194,
|
|
|
-// 203, 212, 220, 228, 235, 240, 245,
|
|
|
-// 249, 252, 254, 255, 254, 252, 249,
|
|
|
-// 245, 240, 235, 228, 220, 212, 203,
|
|
|
-// 194, 184, 175, 165, 155, 145, 135,
|
|
|
-// 126, 116, 107, 99, 90, 83, 75, 68,
|
|
|
-// 61, 55, 50, 44, 39, 35, 30, 27, 23,
|
|
|
-// 20, 17, 14, 12, 10, 8, 6, 5, 3, 2,
|
|
|
-// 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2,
|
|
|
-// 3, 5, 6, 8, 10, 12, 14, 17, 20, 23,
|
|
|
-// 27, 30, 35, 39, 44, 50, 55, 61};
|
|
|
-// LOCAL uint8_t pulseBuffer[100] = {26, 29, 32, 35, 38, 42, 45, 49,
|
|
|
-// 53, 57, 60, 64, 68, 72, 76, 79,
|
|
|
-// 83, 86, 89, 92, 94, 96, 97, 99,
|
|
|
-// 99, 100, 99, 99, 97, 96, 94, 92,
|
|
|
-// 89, 86, 83, 79, 76, 72, 68, 64,
|
|
|
-// 60, 57, 53, 49, 45, 42, 38, 35,
|
|
|
-// 32, 29, 26, 24, 21, 19, 17, 15,
|
|
|
-// 13, 12, 10, 9, 7, 6, 5, 4, 4,
|
|
|
-// 3, 2, 2, 1, 1, 0, 0, 0, 0, 0,
|
|
|
-// 0, 0, 0, 0, 0, 0, 1, 1, 2, 2,
|
|
|
-// 3, 4, 4, 5, 6, 7, 9, 10, 12,
|
|
|
-// 13, 15, 17, 19, 21, 24};
|
|
|
-
|
|
|
-LOCAL uint8_t ledState;
|
|
|
-LOCAL os_timer_t statLEDTimer;
|
|
|
-
|
|
|
-
|
|
|
-//#define GPIO_OUTPUT_SET(gpio_no, bit_value)
|
|
|
-// gpio_output_set(bit_value<<gpio_no, ((~bit_value)&0x01)<<gpio_no, 1<<gpio_no,0)
|
|
|
|
|
|
+static const char* TAG = "ws2812 driver";
|
|
|
+
|
|
|
+// static uint8_t pulseBuffer[100] = { 127, 135, 143, 151, 159, 166, 174, 181, 188,
|
|
|
+// 195, 202, 208, 214, 220, 225, 230, 235, 239,
|
|
|
+// 242, 246, 248, 250, 252, 253, 254, 255, 254,
|
|
|
+// 253, 252, 250, 248, 246, 242, 239, 235, 230,
|
|
|
+// 225, 220, 214, 208, 202, 195, 188, 181, 174,
|
|
|
+// 166, 159, 151, 143, 135, 127, 119, 111, 103,
|
|
|
+// 95, 88, 80, 73, 66, 59, 52, 46, 40, 34, 29,
|
|
|
+// 24, 19, 15, 12, 8, 6, 4, 2, 1, 0, 0, 0, 1, 2,
|
|
|
+// 4, 6, 8, 12, 15, 19, 24, 29, 34, 40, 46, 52,
|
|
|
+// 59, 66, 73, 80, 88, 95, 103, 111, 119};
|
|
|
+
|
|
|
+static os_timer_t ws2812_timer;
|
|
|
+static WS2812_CONFIG_t ws2812_config;
|
|
|
+static void ws2812_timer_cb(void);
|
|
|
+static uint8_t init_buffer[3] = {0x00, 0x00, 0x00};
|
|
|
|
|
|
static void send_ws_0(void)
|
|
|
{
|
|
@@ -73,11 +32,8 @@ static void send_ws_0(void)
|
|
|
time = 7; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
|
|
time = 28; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
|
|
#else
|
|
|
- // time = 6; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
|
|
- // time = 10; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
|
|
- //os_printf("Hola\r\n");
|
|
|
- time = 6; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
|
|
|
- time = 10; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT(WSGPIO));
|
|
|
+ time = 2; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
|
|
|
+ time = 3; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT(WSGPIO));
|
|
|
#endif
|
|
|
}
|
|
|
|
|
@@ -88,77 +44,142 @@ static void send_ws_1(void)
|
|
|
time = 15; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
|
|
time = 16; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
|
|
#else
|
|
|
- // time = 10; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
|
|
- // time = 6; while(time--) WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
|
|
- time = 10; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
|
|
|
- time = 6; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT(WSGPIO));
|
|
|
- //os_printf("Hermosa\r\n");
|
|
|
+
|
|
|
+ time = 5; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
|
|
|
+ time = 4; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT(WSGPIO));
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-// void ws2812_outBuffer( uint8_t * buffer, uint16_t length )
|
|
|
-// {
|
|
|
-// ETS_INTR_LOCK(); // why is this different than a normal disable interupts again?
|
|
|
-// uint16_t i;
|
|
|
-// GPIO_OUTPUT_SET(GPIO_ID_PIN(WSGPIO), 0); // set gpio as output (redundent?)
|
|
|
-//
|
|
|
-//
|
|
|
-// for( i = 0; i < length; i++ )
|
|
|
-// {
|
|
|
-// uint8_t mask = 0x80;
|
|
|
-// uint8_t byte = buffer[i];
|
|
|
-// while (mask)
|
|
|
-// {
|
|
|
-// if( byte & mask ) send_ws_1(); else send_ws_0();
|
|
|
-// mask >>= 1;
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// ETS_INTR_LOCK();
|
|
|
-// }
|
|
|
-//
|
|
|
-// void updateLED(void)
|
|
|
-// {
|
|
|
-// uint8_t outBuffer[3] = {0, 0, 0};
|
|
|
-// uint8_t ledValue = pulseBuffer[ledState];
|
|
|
-//
|
|
|
-// if (sysCfg.module_state.searching == TRUE)
|
|
|
-// {
|
|
|
-// outBuffer[0] = ledValue;
|
|
|
-// }
|
|
|
-// else if (sysCfg.module_state.connected == TRUE)
|
|
|
-// {
|
|
|
-// outBuffer[2] = ledValue;
|
|
|
-// }
|
|
|
-// else
|
|
|
-// {
|
|
|
-// outBuffer[1] = ledValue;
|
|
|
-// }
|
|
|
-// ws2812_outBuffer(outBuffer, sizeof(outBuffer));
|
|
|
-// ledState++;
|
|
|
-// if (ledState == sizeof(pulseBuffer))
|
|
|
-// ledState = 0;
|
|
|
-// }
|
|
|
-//
|
|
|
-// void ws2812_shutdown(void)
|
|
|
-// {
|
|
|
-// os_timer_disarm(&statLEDTimer);
|
|
|
-// uint8_t i, outBuf[3] = {0x00, 0x00, 0x00};
|
|
|
-// for(i=0;i<6;i++)
|
|
|
-// {
|
|
|
-// outBuf[1] = outBuf[1] ^ 0xFF;
|
|
|
-// ws2812_outBuffer(outBuf, sizeof(outBuf));
|
|
|
-// os_delay_us(500000);
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// void ws2812_init(void)
|
|
|
-// {
|
|
|
-// sin(0);
|
|
|
-// ledState = 0;
|
|
|
-// uint8_t initBuffer[3] = {0x00, 0x00, 0x00};
|
|
|
-// ws2812_outBuffer(initBuffer, sizeof(initBuffer));
|
|
|
-// os_timer_disarm(&statLEDTimer); // disarm health publish timer
|
|
|
-// os_timer_setfn(&statLEDTimer, (os_timer_func_t *)updateLED, NULL); // attach function for health publish
|
|
|
-// os_timer_arm(&statLEDTimer, LEDUPDATEDELAY, 1); // activate health packet timer
|
|
|
-// }
|
|
|
+void WS2812_OutBuffer(int8_t * buffer, uint16_t length)
|
|
|
+{
|
|
|
+ ETS_INTR_LOCK(); // why is this different than a normal disable interupts again?
|
|
|
+ uint16_t i;
|
|
|
+ GPIO_OUTPUT_SET(GPIO_ID_PIN(WSGPIO), 0); // set gpio as output (redundent?)
|
|
|
+
|
|
|
+
|
|
|
+ for( i = 0; i < length; i++ )
|
|
|
+ {
|
|
|
+ uint8_t mask = 0x80;
|
|
|
+ uint8_t byte = buffer[i];
|
|
|
+ while (mask)
|
|
|
+ {
|
|
|
+ if( byte & mask ) send_ws_1(); else send_ws_0();
|
|
|
+ mask >>= 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ETS_INTR_UNLOCK();
|
|
|
+}
|
|
|
+
|
|
|
+void ICACHE_FLASH_ATTR WS2812_SetColor(WS2812_COLOR_et color, WS2812_PATTERN_et pattern)
|
|
|
+{
|
|
|
+ ws2812_config.color = color; // store color
|
|
|
+ ws2812_config.pattern = pattern; // store pattern
|
|
|
+ ws2812_config.led_state = 1; // reset led update timer state
|
|
|
+ ws2812_config.direction = WS2812_UP; // set direction for pulse
|
|
|
+ os_timer_disarm(&ws2812_timer); // disarm health publish timer
|
|
|
+
|
|
|
+ switch (ws2812_config.color)
|
|
|
+ {
|
|
|
+ case WS2812_OFF:
|
|
|
+ {
|
|
|
+ ws2812_config.color_mask[WS2812_RED_INDEX] = 0x00;
|
|
|
+ ws2812_config.color_mask[WS2812_GREEN_INDEX] = 0x00;
|
|
|
+ ws2812_config.color_mask[WS2812_BLUE_INDEX] = 0x00;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case WS2812_RED:
|
|
|
+ {
|
|
|
+ ws2812_config.color_mask[WS2812_RED_INDEX] = 0xFF;
|
|
|
+ ws2812_config.color_mask[WS2812_GREEN_INDEX] = 0x00;
|
|
|
+ ws2812_config.color_mask[WS2812_BLUE_INDEX] = 0x00;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case WS2812_BLUE:
|
|
|
+ {
|
|
|
+ ws2812_config.color_mask[WS2812_RED_INDEX] = 0x00;
|
|
|
+ ws2812_config.color_mask[WS2812_GREEN_INDEX] = 0x00;
|
|
|
+ ws2812_config.color_mask[WS2812_BLUE_INDEX] = 0xFF;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case WS2812_GREEN:
|
|
|
+ {
|
|
|
+ ws2812_config.color_mask[WS2812_RED_INDEX] = 0x00;
|
|
|
+ ws2812_config.color_mask[WS2812_GREEN_INDEX] = 0xFF;
|
|
|
+ ws2812_config.color_mask[WS2812_BLUE_INDEX] = 0x00;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case WS2812_MAGENTA:
|
|
|
+ {
|
|
|
+ ws2812_config.color_mask[WS2812_RED_INDEX] = 0xFF;
|
|
|
+ ws2812_config.color_mask[WS2812_GREEN_INDEX] = 0x00;
|
|
|
+ ws2812_config.color_mask[WS2812_BLUE_INDEX] = 0xFF;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case WS2812_ORANGE:
|
|
|
+ {
|
|
|
+ ws2812_config.color_mask[WS2812_RED_INDEX] = 0xFF;
|
|
|
+ ws2812_config.color_mask[WS2812_GREEN_INDEX] = 0xA5;
|
|
|
+ ws2812_config.color_mask[WS2812_BLUE_INDEX] = 0x00;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ ws2812_config.color_mask[WS2812_RED_INDEX] = 0x00;
|
|
|
+ ws2812_config.color_mask[WS2812_GREEN_INDEX] = 0x00;
|
|
|
+ ws2812_config.color_mask[WS2812_BLUE_INDEX] = 0x00;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (ws2812_config.pattern)
|
|
|
+ {
|
|
|
+ case(WS2812_SOLID):
|
|
|
+ {
|
|
|
+ //WS2812_OutBuffer(init_buffer, 3);
|
|
|
+ //os_delay_us(70);
|
|
|
+ WS2812_OutBuffer(ws2812_config.color_mask, 3); //
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case(WS2812_PULSE):
|
|
|
+ {
|
|
|
+ os_timer_setfn(&ws2812_timer, (os_timer_func_t *)ws2812_timer_cb, NULL);
|
|
|
+ os_timer_arm(&ws2812_timer, WS2812_REFRESH_INTERVAL, 1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+void ws2812_timer_cb(void)
|
|
|
+{
|
|
|
+ // calculate color fade
|
|
|
+ uint8_t led_state = ws2812_config.led_state;
|
|
|
+ uint8_t tempBuffer[3] = {ws2812_config.color_mask[WS2812_GREEN_INDEX] / led_state,
|
|
|
+ ws2812_config.color_mask[WS2812_RED_INDEX] / led_state,
|
|
|
+ ws2812_config.color_mask[WS2812_BLUE_INDEX] / led_state};
|
|
|
+
|
|
|
+ // Debuging Information
|
|
|
+ //ESP_LOGV(TAG, "WS2812 Timer [led_state]: %d", ws2812_config.led_state);
|
|
|
+ //ESP_LOGV(TAG, "WS2812 Timer [tempBuffer] %d:%d:%d", tempBuffer[0], tempBuffer[1], tempBuffer[2]);
|
|
|
+
|
|
|
+ WS2812_OutBuffer(tempBuffer, 3); // send color to LED
|
|
|
+
|
|
|
+ // increase / decrease scaling factor for LED color
|
|
|
+ if (ws2812_config.direction == WS2812_UP)
|
|
|
+ {
|
|
|
+ ws2812_config.led_state++;
|
|
|
+ if (ws2812_config.led_state == 50)
|
|
|
+ ws2812_config.direction = WS2812_DOWN;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ws2812_config.led_state--;
|
|
|
+ if (ws2812_config.led_state == 1)
|
|
|
+ ws2812_config.direction = WS2812_UP;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|