avr/sk6812: improved protocol implementation.

still doesn't work with new 5m LED strips from BTF-Lighting (1m strips
do work, as do older 5m stripes).
This commit is contained in:
Martin Preuss
2025-05-14 01:48:24 +02:00
parent b63d625d12
commit 147f920eb6

View File

@@ -154,92 +154,73 @@ sk6812SendPattern_loop2:
sk6812SendQuadruple:
mov r16, r19 ; G
rcall sk6812SendByte2 ; (r16, r17, r24, r25)
rcall sk6812SendByte4 ; (r16, r17, r24, r25)
mov r16, r18 ; R
rcall sk6812SendByte2 ; (r16, r17, r24, r25)
rcall sk6812SendByte4 ; (r16, r17, r24, r25)
mov r16, r20 ; B
rcall sk6812SendByte2 ; (r16, r17, r24, r25)
rcall sk6812SendByte4 ; (r16, r17, r24, r25)
mov r16, r21 ; W
rcall sk6812SendByte2 ; (r16, r17, r24, r25)
rcall sk6812SendByte4 ; (r16, r17, r24, r25)
ret
; @end
#if 0
; ---------------------------------------------------------------------------
; @routine sk6812SendByte
; @macro M_SK6812_HANDLEBIT
.macro M_SK6812_HANDLEBIT
lsl r16 ; +1
brcs l_sendOne ; +1 if false, +2 if branch taken
; send ZERO
nop ; +1
out SK6812_PORT, r25 ; +1 HIGH
nop
nop
nop
out SK6812_PORT, r24 ; +1
nop ; +1
rjmp l_end ; +2
l_sendOne:
out SK6812_PORT, r25 ; +1 HIGH
nop ; +1
nop ; +1
nop ; +1
nop ; +1
nop ; +1
out SK6812_PORT, r24 ; +1
nop ; +1
l_end:
.endmacro
; @end
; ---------------------------------------------------------------------------
; @routine sk6812SendByte4
;
; reset: 80microsecs
; 0: 300ns high, 900ns low (+/- 150ns)
; 1: 600ns high, 600ns low (+/- 150ns)
; 0: 500ns high, 750ns low (+/- 150ns)
; 1: 750ns high, 500ns low (+/- 150ns)
; 8 ticks per cycle
;
; @param r16 value
; @clobbers r16, r17, r24, r25
sk6812SendByte:
ldi r17, 8 ; +1
ldi r24, (1<<SK6812_PINNUM)
clr r25
sk6812SendByte_loop:
lsl r16 ; +1
brcs sk6812SendByte_sendOne ; +1 if false, +2 if branch taken
nop ; +1
; send ZERO
out SK6812_PORT, r24 ; +1 set HIGH
nop ; +1
out SK6812_PORT, r25 ; +1 set LOW
dec r17 ; +1
brne sk6812SendByte_loop ; +1 if false, +2 if branch taken
ret ; 4
sk6812SendByte_sendOne:
out SK6812_PORT, r24 ; +1 set HIGH
nop ; +1
nop ; +1
nop ; +1
nop ; +1
out SK6812_PORT, r25 ; +1 set LOW
dec r17 ; +1
brne sk6812SendByte_loop ; +2
ret
; @end
#endif
sk6812SendByte4:
ldi r24, 0
ldi r25, (1<<SK6812_PINNUM)
M_SK6812_HANDLEBIT
M_SK6812_HANDLEBIT
M_SK6812_HANDLEBIT
M_SK6812_HANDLEBIT
; ---------------------------------------------------------------------------
; @routine sk6812SendByte2
;
; reset: 80microsecs
; 0: 300ns high, 900ns low (+/- 150ns)
; 1: 600ns high, 600ns low (+/- 150ns)
;
; @param r16 value
; @clobbers r16, r17
sk6812SendByte2:
ldi r17, 8 ; +1
sk6812SendByte2_loop:
lsl r16 ; +1
brcs sk6812SendByte2_sendOne ; +1 if false, +2 if branch taken
nop ; +1
; send ZERO
sbi SK6812_PORT, SK6812_PINNUM ; +2 set HIGH
nop ; +1 (125ns)
cbi SK6812_PORT, SK6812_PINNUM ; +2 set LOW (250ns)
dec r17 ; +1 (125ns)
brne sk6812SendByte2_loop ; +1 if false, +2 if branch taken
ret ; +4
sk6812SendByte2_sendOne:
sbi SK6812_PORT, SK6812_PINNUM ; +2 set HIGH
nop ; +1 (125ns)
nop ; +1 (125ns)
nop ; +1 (125ns)
cbi SK6812_PORT, SK6812_PINNUM ; +2 set LOW
dec r17 ; +1
brne sk6812SendByte2_loop ; +1 if false, +2 if branch taken
M_SK6812_HANDLEBIT
M_SK6812_HANDLEBIT
M_SK6812_HANDLEBIT
M_SK6812_HANDLEBIT
ret ; +4
; @end