123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /*******************************************************************************
- * 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"
- 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)
- {
- uint8_t time;
- #if WS2811_COMPATIBLE
- 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));
- #else
- 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
- }
- static void send_ws_1(void)
- {
- uint8_t time;
- #if WS2811_COMPATIBLE
- 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));
- #else
- 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(); // 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)
- {
- // return if the color is already set
- if (color == ws2812_config.color && pattern == ws2812_config.pattern)
- {
- return;
- }
- 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;
- }
- }
|