diff options
author | Joel Challis <git@zvecr.com> | 2021-11-25 19:35:06 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-25 19:35:06 +0000 |
commit | 5e9c29da0df045b03ada9278c34f37b22349a6f7 (patch) | |
tree | 3dbe67afa346513de1132e23c636b5ad01bc3550 /platforms | |
parent | 3d0062071133ad76504ede49a66063115c4a06c5 (diff) | |
download | qmk_firmware-5e9c29da0df045b03ada9278c34f37b22349a6f7.tar.gz qmk_firmware-5e9c29da0df045b03ada9278c34f37b22349a6f7.zip |
Tidy up adjustable ws2812 timing (#15299)
Diffstat (limited to 'platforms')
-rw-r--r-- | platforms/avr/drivers/ws2812.c | 11 | ||||
-rw-r--r-- | platforms/chibios/drivers/ws2812.c | 36 | ||||
-rw-r--r-- | platforms/chibios/drivers/ws2812_pwm.c | 2 | ||||
-rw-r--r-- | platforms/chibios/drivers/ws2812_spi.c | 2 |
4 files changed, 11 insertions, 40 deletions
diff --git a/platforms/avr/drivers/ws2812.c b/platforms/avr/drivers/ws2812.c index 77c492cd4c..9150b3c520 100644 --- a/platforms/avr/drivers/ws2812.c +++ b/platforms/avr/drivers/ws2812.c @@ -52,20 +52,15 @@ void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds) { using the fast 800kHz clockless WS2811/2812 protocol. */ -// Timing in ns -#define w_zeropulse 350 -#define w_onepulse 900 -#define w_totalperiod 1250 - // Fixed cycles used by the inner loop #define w_fixedlow 2 #define w_fixedhigh 4 #define w_fixedtotal 8 // Insert NOPs to match the timing, if possible -#define w_zerocycles (((F_CPU / 1000) * w_zeropulse) / 1000000) -#define w_onecycles (((F_CPU / 1000) * w_onepulse + 500000) / 1000000) -#define w_totalcycles (((F_CPU / 1000) * w_totalperiod + 500000) / 1000000) +#define w_zerocycles (((F_CPU / 1000) * WS2812_T0H) / 1000000) +#define w_onecycles (((F_CPU / 1000) * WS2812_T1H + 500000) / 1000000) +#define w_totalcycles (((F_CPU / 1000) * WS2812_TIMING + 500000) / 1000000) // w1_nops - nops between rising edge and falling edge - low #if w_zerocycles >= w_fixedlow diff --git a/platforms/chibios/drivers/ws2812.c b/platforms/chibios/drivers/ws2812.c index 8c882c8eeb..7e870661de 100644 --- a/platforms/chibios/drivers/ws2812.c +++ b/platforms/chibios/drivers/ws2812.c @@ -22,6 +22,12 @@ # define WS2812_OUTPUT_MODE PAL_MODE_OUTPUT_OPENDRAIN #endif +// The reset gap can be 6000 ns, but depending on the LED strip it may have to be increased +// to values like 600000 ns. If it is too small, the pixels will show nothing most of the time. +#ifndef WS2812_RES +# define WS2812_RES (1000 * WS2812_TRST_US) // Width of the low gap between bits to cause a frame to latch +#endif + #define NUMBER_NOPS 6 #define CYCLES_PER_SEC (CPU_CLOCK / NUMBER_NOPS * NOP_FUDGE) #define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives @@ -40,36 +46,6 @@ } \ } while (0) -/* The WS2812 datasheets define T1H 900ns, T0H 350ns, T1L 350ns, T0L 900ns. Hence, by default, these are chosen to be conservative and avoid problems rather than for maximum throughput; in the code, this is done by default using a WS2812_TIMING parameter that accounts for the whole window (1250ns) and defining T1H and T0H; T1L and T0L are obtained by subtracting their low counterparts from the window. -However, there are certain "WS2812"-like LEDs, like the SK6812s, which work in a similar communication topology but use different timings for the window and the T1L, T1H, T0L and T0H. This means that, albeit the same driver being applicable, the timings must be adapted. The following defines are done such that the adjustment of these timings can be done in the keyboard's config.h; if nothing is said, the defines default to the WS2812 ones. -*/ - -#ifndef WS2812_TIMING -# define WS2812_TIMING 1250 -#endif - -#ifndef WS2812_T1H -# define WS2812_T1H 900 // Width of a 1 bit in ns -#endif - -#ifndef WS2812_T1L -# define WS2812_T1L (WS2812_TIMING - WS2812_T1H) // Width of a 1 bit in ns -#endif - -#ifndef WS2812_T0H -# define WS2812_T0H 350 // Width of a 0 bit in ns -#endif - -#ifndef WS2812_T0L -# define WS2812_T0L (WS2812_TIMING - WS2812_T0H) // Width of a 0 bit in ns -#endif - -// The reset gap can be 6000 ns, but depending on the LED strip it may have to be increased -// to values like 600000 ns. If it is too small, the pixels will show nothing most of the time. -#ifndef WS2812_RES -# define WS2812_RES (1000 * WS2812_TRST_US) // Width of the low gap between bits to cause a frame to latch -#endif - void sendByte(uint8_t byte) { // WS2812 protocol wants most significant bits first for (unsigned char bit = 0; bit < 8; bit++) { diff --git a/platforms/chibios/drivers/ws2812_pwm.c b/platforms/chibios/drivers/ws2812_pwm.c index c17b9cd4e5..19ea3cfe8a 100644 --- a/platforms/chibios/drivers/ws2812_pwm.c +++ b/platforms/chibios/drivers/ws2812_pwm.c @@ -71,7 +71,7 @@ * Calculate the number of zeroes to add at the end assuming 1.25 uS/bit: */ #define WS2812_COLOR_BITS (WS2812_CHANNELS * 8) -#define WS2812_RESET_BIT_N (1000 * WS2812_TRST_US / 1250) +#define WS2812_RESET_BIT_N (1000 * WS2812_TRST_US / WS2812_TIMING) #define WS2812_COLOR_BIT_N (RGBLED_NUM * WS2812_COLOR_BITS) /**< Number of data bits */ #define WS2812_BIT_N (WS2812_COLOR_BIT_N + WS2812_RESET_BIT_N) /**< Total number of bits in a frame */ diff --git a/platforms/chibios/drivers/ws2812_spi.c b/platforms/chibios/drivers/ws2812_spi.c index 62722f466e..ba471e0b8e 100644 --- a/platforms/chibios/drivers/ws2812_spi.c +++ b/platforms/chibios/drivers/ws2812_spi.c @@ -77,7 +77,7 @@ #endif #define BYTES_FOR_LED (BYTES_FOR_LED_BYTE * WS2812_CHANNELS) #define DATA_SIZE (BYTES_FOR_LED * RGBLED_NUM) -#define RESET_SIZE (1000 * WS2812_TRST_US / (2 * 1250)) +#define RESET_SIZE (1000 * WS2812_TRST_US / (2 * WS2812_TIMING)) #define PREAMBLE_SIZE 4 static uint8_t txbuf[PREAMBLE_SIZE + DATA_SIZE + RESET_SIZE] = {0}; |