qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

ws2812.h (2995B)


      1 /*
      2  * This program is free software: you can redistribute it and/or modify
      3  * it under the terms of the GNU General Public License as published by
      4  * the Free Software Foundation, either version 2 of the License, or
      5  * (at your option) any later version.
      6  *
      7  * This program is distributed in the hope that it will be useful,
      8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10  * GNU General Public License for more details.
     11  *
     12  * You should have received a copy of the GNU General Public License
     13  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     14  */
     15 
     16 #pragma once
     17 
     18 #include "util.h"
     19 
     20 /*
     21  * The WS2812 datasheets define T1H 900ns, T0H 350ns, T1L 350ns, T0L 900ns. Hence, by default, these
     22  * are chosen to be conservative and avoid problems rather than for maximum throughput; in the code,
     23  * this is done by default using a WS2812_TIMING parameter that accounts for the whole window (1250ns)
     24  * and defining T1H and T0H; T1L and T0L are obtained by subtracting their low counterparts from the window.
     25  *
     26  * However, there are certain "WS2812"-like LEDs, like the SK6812s, which work in a similar
     27  * communication topology but use different timings for the window and the T1L, T1H, T0L and T0H.
     28  * This means that, albeit the same driver being applicable, the timings must be adapted.
     29  */
     30 
     31 #ifndef WS2812_TIMING
     32 #    define WS2812_TIMING 1250
     33 #endif
     34 
     35 #ifndef WS2812_T1H
     36 #    define WS2812_T1H 900 // Width of a 1 bit in ns
     37 #endif
     38 
     39 #ifndef WS2812_T1L
     40 #    define WS2812_T1L (WS2812_TIMING - WS2812_T1H) // Width of a 1 bit in ns
     41 #endif
     42 
     43 #ifndef WS2812_T0H
     44 #    define WS2812_T0H 350 // Width of a 0 bit in ns
     45 #endif
     46 
     47 #ifndef WS2812_T0L
     48 #    define WS2812_T0L (WS2812_TIMING - WS2812_T0H) // Width of a 0 bit in ns
     49 #endif
     50 
     51 /*
     52  * Older WS2812s can handle a reset time (TRST) of 50us, but recent
     53  * component revisions require a minimum of 280us.
     54  */
     55 #if !defined(WS2812_TRST_US)
     56 #    define WS2812_TRST_US 280
     57 #endif
     58 
     59 #if defined(RGBLIGHT_WS2812)
     60 #    define WS2812_LED_COUNT RGBLIGHT_LED_COUNT
     61 #elif defined(RGB_MATRIX_WS2812)
     62 #    define WS2812_LED_COUNT RGB_MATRIX_LED_COUNT
     63 #endif
     64 
     65 #define WS2812_BYTE_ORDER_RGB 0
     66 #define WS2812_BYTE_ORDER_GRB 1
     67 #define WS2812_BYTE_ORDER_BGR 2
     68 
     69 #ifndef WS2812_BYTE_ORDER
     70 #    define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
     71 #endif
     72 
     73 typedef struct PACKED ws2812_led_t {
     74 #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
     75     uint8_t g;
     76     uint8_t r;
     77     uint8_t b;
     78 #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
     79     uint8_t r;
     80     uint8_t g;
     81     uint8_t b;
     82 #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
     83     uint8_t b;
     84     uint8_t g;
     85     uint8_t r;
     86 #endif
     87 #ifdef WS2812_RGBW
     88     uint8_t w;
     89 #endif
     90 } ws2812_led_t;
     91 
     92 void ws2812_init(void);
     93 void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
     94 void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
     95 void ws2812_flush(void);
     96 
     97 void ws2812_rgb_to_rgbw(ws2812_led_t *led);