123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- #include "hal/ws2812.h"
- 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)
- {
- uint8_t time;
- #if WS2811_COMPATIBLE
- 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 = 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 = 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 = 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;
- }
- }
|