diff options
| -rw-r--r-- | drivers/avr/ws2812.c | 35 | ||||
| -rw-r--r-- | drivers/avr/ws2812.h | 4 | ||||
| -rw-r--r-- | keyboards/ergodox_ez/led_i2c.c | 13 |
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 | ||
| 36 | void ws2812_sendarray(uint8_t *array, uint16_t length); | 37 | static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t masklo, uint8_t maskhi); |
| 37 | void ws2812_sendarray_mask(uint8_t *array, uint16_t length, uint8_t pinmask); | ||
| 38 | 38 | ||
| 39 | // Setleds for standard RGB | 39 | // Setleds for standard RGB |
| 40 | void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) { | 40 | void 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 | ||
| 45 | void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask) { | 45 | void 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 | ||
| 58 | void 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 | ||
| 121 | void inline ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi) { | 121 | static 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 | */ |
| 39 | void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds); | 39 | void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds); |
| 40 | void ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pinmask); | 40 | void 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 | ||
| 28 | extern rgblight_config_t rgblight_config; | 28 | extern 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 | |||
| 37 | void ws2812_sendarray(uint8_t *array, uint16_t length); | ||
| 38 | void ws2812_sendarray_mask(uint8_t *array, uint16_t length, uint8_t pinmask); | ||
| 39 | |||
| 40 | |||
| 41 | |||
| 42 | |||
| 43 | void rgblight_set(void) { | 30 | void 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++) { |
