0
\$\begingroup\$

I recently purchased addressable RGB LED strips based on the WS2811 chip. These strips have a single data + clock line that uses NRZ style encoding to distinguish between a 1 and 0. The datasheet for the strip can be found at https://www.adafruit.com/datasheets/WS2811.pdf

Since the timing is strict for these strips, I am trying to use assembly code to drive the strip (my first attempt with assembly).

Using Atmega168 @ 16Mhz (1 clock = 62.5ns), I call the following assembly code (which I expect to set the LED color to WHITE).

asm_pin_toggle:
sbi DDRC, 4

;reset the led strip data line ~50us
ldi R19, 255
loop:
    nop
    dec R19
    brne loop

ldi R19, 23 ;loop 24 times - all 1 bits
loop_all_1:
    sbi PORTC,4
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    cbi PORTC, 4

    dec R19
    brne loop_all_1


ret

However when I run this I get the color GREEN. Any ideas what am I doing wrong?

There are many version of the WS2811 timing floating on the internet. The one I have used is

  • T0H - 250ns
  • T0L - 1000ns
  • T1H - 1000ns
  • T1L - 250ns
  • RET - >= 50us

any help will be much appreciated!

\$\endgroup\$
2
  • \$\begingroup\$ Is there a particular reason why you don't want to use the normal C delay macros? \$\endgroup\$ May 16, 2015 at 5:54
  • \$\begingroup\$ @IgnacioVazquez-Abrams No particular reason except I wanted to use this opportunity to learn bit of assemble as well. \$\endgroup\$
    – Ankit
    May 16, 2015 at 6:02

1 Answer 1

2
\$\begingroup\$

Problem fixed.

I was loading 23 into R19 register(hence the loop was only getting executed 23 times instead of 24).

Fixing that to 24 solved the issue.

\$\endgroup\$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.