|
@@ -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 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 ledState;
|
|
|
-LOCAL os_timer_t statLEDTimer;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
|
|
|
+static const char* TAG = "ws2812 driver";
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+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--) 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--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT(WSGPIO));
|
|
|
- time = 6; while(time--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT(WSGPIO));
|
|
|
-
|
|
|
+
|
|
|
+ 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(int8_t * buffer, uint16_t length)
|
|
|
+{
|
|
|
+ ETS_INTR_LOCK();
|
|
|
+ uint16_t i;
|
|
|
+ GPIO_OUTPUT_SET(GPIO_ID_PIN(WSGPIO), 0);
|
|
|
+
|
|
|
+
|
|
|
+ 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;
|
|
|
+ ws2812_config.pattern = pattern;
|
|
|
+ ws2812_config.led_state = 1;
|
|
|
+ ws2812_config.direction = WS2812_UP;
|
|
|
+ os_timer_disarm(&ws2812_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(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)
|
|
|
+{
|
|
|
+
|
|
|
+ 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};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ WS2812_OutBuffer(tempBuffer, 3);
|
|
|
+
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|