I'm trying to use the light_ws2812 library to drive WS2812 LEDs from an ATTiny414. The core of that library is an inline assembly snippet that bitbangs the serial line. here it is with the timing-nops stripped out:
void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi) { uint8_t curbyte,ctr,masklo; uint8_t sreg_prev; ws2812_DDRREG |= maskhi; // Enable output masklo =~maskhi&ws2812_PORTREG; maskhi |= ws2812_PORTREG; sreg_prev=SREG; cli(); while (datlen--) { curbyte=*data++; asm volatile( " ldi %0,8 \n\t" "loop%=: \n\t" " out %2,%3 \n\t" // '1' [01] '0' [01] - re " sbrs %1,7 \n\t" // '1' [03] '0' [02] " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low " lsl %1 \n\t" // '1' [04] '0' [04] " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high " dec %0 \n\t" // '1' [+2] '0' [+2] " brne loop%=\n\t" // '1' [+3] '0' [+4] : "=&d" (ctr) : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) ); } SREG=sreg_prev; } An obvious difference between the 'regular AVR' and the ATTiny*14 series C definitions is that the IO registers aren't called DDRx and PORTx but PORTx.DIR and PORTx. I already fixed that in the light_ws2812 header and it seems to work fine.
After this I am however getting an error with the assembly operand 2 ("I" (_SFR_IO_ADDR(ws2812_PORTREG))):
lib/light_ws2812.c: In function 'ws2812_sendarray_mask': lib/light_ws2812.c:119:5: warning: asm operand 2 probably doesn't match constraints asm volatile( ^~~ lib/light_ws2812.c:119:5: error: impossible constraint in 'asm' make: *** [Makefile:28: lib/light_ws2812.o] Error 1 I also tried using a lowercase i as the constraint instead of the I, which changes the error to
/tmp/ccBR4JKE.s:48: Error: operand out of range: 1028 Looking at the datasheet this value makes sense, PORTA starts at 0x400 (1024) and the PORTx.OUT register has an additional offset of 4 bytes, placing PORTA.OUT at 0x404 = 1028.
with a 16-bit register constraint like x or w it compiles but then I get a linker error:
avr-ld: lib/light_ws2812.o: in function `loop32': light_ws2812.c:(.text+0x38): undefined reference to `r30' I am compiling this using avr-gcc and avr-ld, with a current avr-libc that I manually added the relevant files from the Atmel ATtiny Series Device Support package to.
VPORTA.OUTregister instead? It starts at0x0so unlikePORTA.OUTit should fit intoi... \$\endgroup\$