Browse Source

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
Joel Challis 6 years ago
parent
commit
31fd0cbc1c
3 changed files with 17 additions and 35 deletions
  1. 15 20
      drivers/avr/ws2812.c
  2. 2 2
      drivers/avr/ws2812.h
  3. 0 13
      keyboards/ergodox_ez/led_i2c.c

+ 15 - 20
drivers/avr/ws2812.c

@@ -20,12 +20,13 @@
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
  */
-
 #include "ws2812.h"
 #include "ws2812.h"
 #include <avr/interrupt.h>
 #include <avr/interrupt.h>
 #include <avr/io.h>
 #include <avr/io.h>
 #include <util/delay.h>
 #include <util/delay.h>
 
 
+#define pinmask(pin) (_BV((pin)&0xF))
+
 /*
 /*
  * Forward declare internal functions
  * Forward declare internal functions
  *
  *
@@ -33,20 +34,21 @@
  * The length is the number of bytes to send - three per LED.
  * The length is the number of bytes to send - three per LED.
  */
  */
 
 
-void ws2812_sendarray(uint8_t *array, uint16_t length);
-void ws2812_sendarray_mask(uint8_t *array, uint16_t length, uint8_t pinmask);
+static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t masklo, uint8_t maskhi);
 
 
 // Setleds for standard RGB
 // Setleds for standard RGB
-void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) {
-    // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
-    ws2812_setleds_pin(ledarray, leds, _BV(RGB_DI_PIN & 0xF));
+void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds) {
+    // wrap up usage of RGB_DI_PIN
+    ws2812_setleds_pin(ledarray, number_of_leds, RGB_DI_PIN);
 }
 }
 
 
-void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask) {
-    // new universal format (DDR)
-    _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= pinmask;
+void ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pin) {
+    DDRx_ADDRESS(RGB_DI_PIN) |= pinmask(pin);
 
 
-    ws2812_sendarray_mask((uint8_t *)ledarray, leds * sizeof(LED_TYPE), pinmask);
+    uint8_t masklo = ~(pinmask(pin)) & PORTx_ADDRESS(pin);
+    uint8_t maskhi = pinmask(pin) | PORTx_ADDRESS(pin);
+
+    ws2812_sendarray_mask((uint8_t *)ledarray, number_of_leds * sizeof(LED_TYPE), masklo, maskhi);
 
 
 #ifdef RGBW
 #ifdef RGBW
     _delay_us(80);
     _delay_us(80);
@@ -55,8 +57,6 @@ void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmas
 #endif
 #endif
 }
 }
 
 
-void ws2812_sendarray(uint8_t *data, uint16_t datlen) { ws2812_sendarray_mask(data, datlen, _BV(RGB_DI_PIN & 0xF)); }
-
 /*
 /*
   This routine writes an array of bytes with RGB values to the Dataout pin
   This routine writes an array of bytes with RGB values to the Dataout pin
   using the fast 800kHz clockless WS2811/2812 protocol.
   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
 #define w_nop8 w_nop4 w_nop4
 #define w_nop8 w_nop4 w_nop4
 #define w_nop16 w_nop8 w_nop8
 #define w_nop16 w_nop8 w_nop8
 
 
-void inline ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi) {
-    uint8_t curbyte, ctr, masklo;
-    uint8_t sreg_prev;
+static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t masklo, uint8_t maskhi) {
+    uint8_t curbyte, ctr, sreg_prev;
 
 
-    // masklo  =~maskhi&ws2812_PORTREG;
-    // maskhi |=        ws2812_PORTREG;
-    masklo = ~maskhi & _SFR_IO8((RGB_DI_PIN >> 4) + 2);
-    maskhi |= _SFR_IO8((RGB_DI_PIN >> 4) + 2);
     sreg_prev = SREG;
     sreg_prev = SREG;
     cli();
     cli();
 
 
@@ -188,7 +183,7 @@ void inline ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi
                      "       dec   %0    \n\t"  //  '1' [+2] '0' [+2]
                      "       dec   %0    \n\t"  //  '1' [+2] '0' [+2]
                      "       brne  loop%=\n\t"  //  '1' [+3] '0' [+4]
                      "       brne  loop%=\n\t"  //  '1' [+3] '0' [+4]
                      : "=&d"(ctr)
                      : "=&d"(ctr)
-                     : "r"(curbyte), "I"(_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r"(maskhi), "r"(masklo));
+                     : "r"(curbyte), "I"(_SFR_IO_ADDR(PORTx_ADDRESS(RGB_DI_PIN))), "r"(maskhi), "r"(masklo));
     }
     }
 
 
     SREG = sreg_prev;
     SREG = sreg_prev;

+ 2 - 2
drivers/avr/ws2812.h

@@ -29,7 +29,7 @@
  * Input:
  * Input:
  *         ledarray:           An array of GRB data describing the LED colors
  *         ledarray:           An array of GRB data describing the LED colors
  *         number_of_leds:     The number of LEDs to write
  *         number_of_leds:     The number of LEDs to write
- *         pinmask (optional): Bitmask describing the output bin. e.g. _BV(PB0)
+ *         pin (optional):     A pin_t definition for the line to drive
  *
  *
  * The functions will perform the following actions:
  * The functions will perform the following actions:
  *         - Set the data-out pin as output
  *         - Set the data-out pin as output
@@ -37,4 +37,4 @@
  *         - Wait 50us to reset the LEDs
  *         - Wait 50us to reset the LEDs
  */
  */
 void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds);
 void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds);
-void ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pinmask);
+void ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pin);

+ 0 - 13
keyboards/ergodox_ez/led_i2c.c

@@ -27,19 +27,6 @@
 
 
 extern rgblight_config_t rgblight_config;
 extern rgblight_config_t rgblight_config;
 
 
-/*
- * Forward declare internal functions
- *
- * The functions take a byte-array and send to the data output as WS2812 bitstream.
- * The length is the number of bytes to send - three per LED.
- */
-
-void ws2812_sendarray(uint8_t *array, uint16_t length);
-void ws2812_sendarray_mask(uint8_t *array, uint16_t length, uint8_t pinmask);
-
-
-
-
 void rgblight_set(void) {
 void rgblight_set(void) {
     if (!rgblight_config.enable) {
     if (!rgblight_config.enable) {
         for (uint8_t i = 0; i < RGBLED_NUM; i++) {
         for (uint8_t i = 0; i < RGBLED_NUM; i++) {