Skip to content

Instantly share code, notes, and snippets.

@nrdmn
Last active November 6, 2021 16:56
Show Gist options
  • Save nrdmn/b1331feb1936b9bc3410f0b926b81490 to your computer and use it in GitHub Desktop.
Save nrdmn/b1331feb1936b9bc3410f0b926b81490 to your computer and use it in GitHub Desktop.
ws2812 for avr, 16 MHz. follows gcc abi, restores interrupts if necessary. 64 bytes.
.equ PORTB, 5
; void ws2812(const char *ptr, const size_t n);
.global ws2812
ws2812:
; Move ptr (r24, r25) to X (r26, r27)
movw X, r24
; Move n (r22, r23) to r24, r25
movw r24, r22
; r1 starts out as zero
; Are interrupts disabled? If yes, skip
brid 1f
; If not, set r1 to 0xff
dec r1
1:
; Disable interrupts
cli
2:
; Main loop starts here
; T = 11
; Decrement n
sbiw r24, 1
; T = 13
; Turn off IO port in case it is still on
cbi PORTB, 5
; T = 15
; If decrement underflowed, exit loop
brlt 8f
; We're looking at a new byte here
; T = 16
; Set our bit index to 8 ...
ldi r19, 8
; T = 17
; ... and fetch byte from *X, incrementing X afterwards
ld r18, X+
3:
; T = 19
; Left-shift the byte we have fetched ...
lsl r18
; T = 0
; Bit starts here
sbi PORTB, 5
; T = 2
; Wait two clock cycles
rjmp 4f
4:
; T = 4
; ... and branch if MSB was 0
brcc 7f
; If we're here, we're sending a '1' bit
; T = 5
; Wait three clock cycles
lpm
; T = 8
; Decrement bit index
dec r19
; T = 9
; If bit index hit zero, branch to start
breq 2b
; T = 10
; Otherwise, wait three more clock cycles
lpm
5:
; T = 13
; Turn off IO port in case it is still on
cbi PORTB, 5
; T = 15
; Wait two clock cycles
rjmp 6f
6:
; T = 17
; Go process the next bit
rjmp 3b
7:
; Here, we're sending a 0 bit
; T = 6
; Decrement bit index
dec r19
; T = 7
; Turn off IO port
cbi PORTB, 5
; T = 9
; If bit index hit zero, branch to start
breq 2b
; T = 10
; Otherwise, finish this bit and process the next
jmp 5b
8:
; End of loop
; If interrupts were disabled, skip
sbrc r1, 0
; Otherwise, re-enable them
sei
; r1 can be 0 or 0xff
; Either way, decrement until it is 0 again
; The following loop wait approximately 64 us
9:
nop
dec r1
brne 9b
ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment