20
20
* You should have received a copy of the GNU General Public License
21
21
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22
22
*/
23
-
24
23
#include "ws2812.h"
25
24
#include <avr/interrupt.h>
26
25
#include <avr/io.h>
27
26
#include <util/delay.h>
28
27
28
+ #define pinmask (pin ) (_BV((pin)&0xF))
29
+
29
30
/*
30
31
* Forward declare internal functions
31
32
*
32
33
* The functions take a byte-array and send to the data output as WS2812 bitstream.
33
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
- void ws2812_sendarray_mask (uint8_t * array , uint16_t length , uint8_t pinmask );
37
+ static inline void ws2812_sendarray_mask (uint8_t * data , uint16_t datlen , uint8_t masklo , uint8_t maskhi );
38
38
39
39
// Setleds for standard RGB
40
- void inline ws2812_setleds (LED_TYPE * ledarray , uint16_t leds ) {
41
- // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
42
- ws2812_setleds_pin (ledarray , leds , _BV ( RGB_DI_PIN & 0xF ) );
40
+ void inline ws2812_setleds (LED_TYPE * ledarray , uint16_t number_of_leds ) {
41
+ // wrap up usage of RGB_DI_PIN
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 ) {
46
- // new universal format (DDR)
47
- _SFR_IO8 ((RGB_DI_PIN >> 4 ) + 1 ) |= pinmask ;
45
+ void ws2812_setleds_pin (LED_TYPE * ledarray , uint16_t number_of_leds , uint8_t pin ) {
46
+ DDRx_ADDRESS (RGB_DI_PIN ) |= pinmask (pin );
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
53
#ifdef RGBW
52
54
_delay_us (80 );
@@ -55,8 +57,6 @@ void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmas
55
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
61
This routine writes an array of bytes with RGB values to the Dataout pin
62
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
118
#define w_nop8 w_nop4 w_nop4
119
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 ) {
122
- uint8_t curbyte , ctr , masklo ;
123
- uint8_t sreg_prev ;
121
+ static inline void ws2812_sendarray_mask (uint8_t * data , uint16_t datlen , uint8_t masklo , uint8_t maskhi ) {
122
+ uint8_t curbyte , ctr , 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
124
sreg_prev = SREG ;
130
125
cli ();
131
126
@@ -188,7 +183,7 @@ void inline ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi
188
183
" dec %0 \n\t" // '1' [+2] '0' [+2]
189
184
" brne loop%=\n\t" // '1' [+3] '0' [+4]
190
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
189
SREG = sreg_prev ;
0 commit comments