summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2020-04-02 20:46:38 +0100
committerGitHub <noreply@github.com>2020-04-02 20:46:38 +0100
commit31fd0cbc1ca35ce023fbbc3553a04aa480dc2187 (patch)
treeb561d6508598fe03073f85adb395d0a2498b5901
parent2b427f774a6665819306cf716d79355db3f7d169 (diff)
Fix AVR ws2812 when ADDRESS_BASE is non zero (#8646)
* Fix AVR ws2812 when ADDRESS_BASE is non zero * fix port * remove unused function defs
-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 82d985c20a..5c3d72dcb5 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 b869fb28c8..88eb081894 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 4a7a02f468..7c1ccdec5a 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++) {