/* This routine writes an array of bytes with RGB values to the Dataout port using the fast 800kHz clockless WS2811/2812 protocol. */ #include "WS2812.h" // Timing in ns #define w_zeropulse 350 #define w_onepulse 900 #define w_totalperiod 1250 void ws2812_init() { ws2812_DDREG |= mask; // Enable DDR } #define w_nop1 "nop \n\t" #define w_nop2 "rjmp .+0 \n\t" void ws2812_sendarray(uint8_t *data, uint16_t datlen) { uint8_t curbyte,ctr; uint8_t sreg_prev; sreg_prev=SREG; cli(); while (datlen--) { curbyte=*data++; asm volatile( " ldi %0,8 \n\t" "loop%=: \n\t" " st X,%3 \n\t" // '1' [02] '0' [02] - re w_nop1 w_nop2 " sbrs %1,7 \n\t" // '1' [04] '0' [03] " st X,%4 \n\t" // '1' [--] '0' [05] - fe-low " lsl %1 \n\t" // '1' [05] '0' [06] w_nop1 w_nop1 w_nop2 w_nop2 " brcc skipone%= \n\t" // '1' [+1] '0' [+2] - " st X,%4 \n\t" // '1' [+3] '0' [--] - fe-high "skipone%=: " // '1' [+3] '0' [+2] - w_nop1 w_nop2 " dec %0 \n\t" // '1' [+4] '0' [+3] " brne loop%=\n\t" // '1' [+5] '0' [+4] : "=&d" (ctr) : "r" (curbyte), "x" (&ws2812_PORTREG), "r" (mask), "r" (~mask) ); } SREG=sreg_prev; }