aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/avr/ws2812.c35
-rw-r--r--drivers/avr/ws2812.h4
-rw-r--r--keyboards/ergodox_ez/led_i2c.c13
3 files changed, 17 insertions, 35 deletions
diff --git a/drivers/avr/ws2812.c b/drivers/avr/ws2812.c
index 82d985c20..5c3d72dcb 100644
--- a/drivers/avr/ws2812.c
+++ b/drivers/avr/ws2812.c
@@ -20,12 +20,13 @@
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */ 22 */
23
24#include "ws2812.h" 23#include "ws2812.h"
25#include <avr/interrupt.h> 24#include <avr/interrupt.h>
26#include <avr/io.h> 25#include <avr/io.h>
27#include <util/delay.h> 26#include <util/delay.h>
28 27
28#define pinmask(pin) (_BV((pin)&0xF))
29
29/* 30/*
30 * Forward declare internal functions 31 * Forward declare internal functions
31 * 32 *
@@ -33,20 +34,21 @@
33 * The length is the number of bytes to send - three per LED. 34 * The length is the number of bytes to send - three per LED.
34 */ 35 */
35 36
36void ws2812_sendarray(uint8_t *array, uint16_t length); 37static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t masklo, uint8_t maskhi);
37void ws2812_sendarray_mask(uint8_t *array, uint16_t length, uint8_t pinmask);
38 38
39// Setleds for standard RGB 39// Setleds for standard RGB
40void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) { 40void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds) {
41 // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); 41 // wrap up usage of RGB_DI_PIN
42 ws2812_setleds_pin(ledarray, leds, _BV(RGB_DI_PIN & 0xF)); 42 ws2812_setleds_pin(ledarray, number_of_leds, RGB_DI_PIN);
43} 43}
44 44
45void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask) { 45void ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pin) {
46 // new universal format (DDR) 46 DDRx_ADDRESS(RGB_DI_PIN) |= pinmask(pin);
47 _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= pinmask;
48 47
49 ws2812_sendarray_mask((uint8_t *)ledarray, leds * sizeof(LED_TYPE), pinmask); 48 uint8_t masklo = ~(pinmask(pin)) & PORTx_ADDRESS(pin);
49 uint8_t maskhi = pinmask(pin) | PORTx_ADDRESS(pin);
50
51 ws2812_sendarray_mask((uint8_t *)ledarray, number_of_leds * sizeof(LED_TYPE), masklo, maskhi);
50 52
51#ifdef RGBW 53#ifdef RGBW
52 _delay_us(80); 54 _delay_us(80);
@@ -55,8 +57,6 @@ void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmas
55#endif 57#endif
56} 58}
57 59
58void ws2812_sendarray(uint8_t *data, uint16_t datlen) { ws2812_sendarray_mask(data, datlen, _BV(RGB_DI_PIN & 0xF)); }
59
60/* 60/*
61 This routine writes an array of bytes with RGB values to the Dataout pin 61 This routine writes an array of bytes with RGB values to the Dataout pin
62 using the fast 800kHz clockless WS2811/2812 protocol. 62 using the fast 800kHz clockless WS2811/2812 protocol.
@@ -118,14 +118,9 @@ void ws2812_sendarray(uint8_t *data, uint16_t datlen) { ws2812_sendarray_mask(da
118#define w_nop8 w_nop4 w_nop4 118#define w_nop8 w_nop4 w_nop4
119#define w_nop16 w_nop8 w_nop8 119#define w_nop16 w_nop8 w_nop8
120 120
121void inline ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi) { 121static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t masklo, uint8_t maskhi) {
122 uint8_t curbyte, ctr, masklo; 122 uint8_t curbyte, ctr, sreg_prev;
123 uint8_t sreg_prev;
124 123
125 // masklo =~maskhi&ws2812_PORTREG;
126 // maskhi |= ws2812_PORTREG;
127 masklo = ~maskhi & _SFR_IO8((RGB_DI_PIN >> 4) + 2);
128 maskhi |= _SFR_IO8((RGB_DI_PIN >> 4) + 2);
129 sreg_prev = SREG; 124 sreg_prev = SREG;
130 cli(); 125 cli();
131 126
@@ -188,7 +183,7 @@ void inline ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi
188 " dec %0 \n\t" // '1' [+2] '0' [+2] 183 " dec %0 \n\t" // '1' [+2] '0' [+2]
189 " brne loop%=\n\t" // '1' [+3] '0' [+4] 184 " brne loop%=\n\t" // '1' [+3] '0' [+4]
190 : "=&d"(ctr) 185 : "=&d"(ctr)
191 : "r"(curbyte), "I"(_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r"(maskhi), "r"(masklo)); 186 : "r"(curbyte), "I"(_SFR_IO_ADDR(PORTx_ADDRESS(RGB_DI_PIN))), "r"(maskhi), "r"(masklo));
192 } 187 }
193 188
194 SREG = sreg_prev; 189 SREG = sreg_prev;
diff --git a/drivers/avr/ws2812.h b/drivers/avr/ws2812.h
index b869fb28c..88eb08189 100644
--- a/drivers/avr/ws2812.h
+++ b/drivers/avr/ws2812.h
@@ -29,7 +29,7 @@
29 * Input: 29 * Input:
30 * ledarray: An array of GRB data describing the LED colors 30 * ledarray: An array of GRB data describing the LED colors
31 * number_of_leds: The number of LEDs to write 31 * number_of_leds: The number of LEDs to write
32 * pinmask (optional): Bitmask describing the output bin. e.g. _BV(PB0) 32 * pin (optional): A pin_t definition for the line to drive
33 * 33 *
34 * The functions will perform the following actions: 34 * The functions will perform the following actions:
35 * - Set the data-out pin as output 35 * - Set the data-out pin as output
@@ -37,4 +37,4 @@
37 * - Wait 50us to reset the LEDs 37 * - Wait 50us to reset the LEDs
38 */ 38 */
39void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds); 39void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds);
40void ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pinmask); 40void ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pin);
diff --git a/keyboards/ergodox_ez/led_i2c.c b/keyboards/ergodox_ez/led_i2c.c
index 4a7a02f46..7c1ccdec5 100644
--- a/keyboards/ergodox_ez/led_i2c.c
+++ b/keyboards/ergodox_ez/led_i2c.c
@@ -27,19 +27,6 @@
27 27
28extern rgblight_config_t rgblight_config; 28extern rgblight_config_t rgblight_config;
29 29
30/*
31 * Forward declare internal functions
32 *
33 * The functions take a byte-array and send to the data output as WS2812 bitstream.
34 * The length is the number of bytes to send - three per LED.
35 */
36
37void ws2812_sendarray(uint8_t *array, uint16_t length);
38void ws2812_sendarray_mask(uint8_t *array, uint16_t length, uint8_t pinmask);
39
40
41
42
43void rgblight_set(void) { 30void rgblight_set(void) {
44 if (!rgblight_config.enable) { 31 if (!rgblight_config.enable) {
45 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 32 for (uint8_t i = 0; i < RGBLED_NUM; i++) {