diff options
Diffstat (limited to 'libleds_asm.S')
| -rw-r--r-- | libleds_asm.S | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/libleds_asm.S b/libleds_asm.S new file mode 100644 index 0000000..fd7e67c --- /dev/null +++ b/libleds_asm.S @@ -0,0 +1,92 @@ +.include "m16def.inc" + +#ifndef F_CPU +# error The LEDs are timing sensitive. F_CPU required. +#elif F_CPU < 4000000 +# error The LEDs are timing sensitive. CPU Frequency must be at least 4MHz +#elif F_CPU == 4000000 + +// 4MHz +#define nop_short +#define nop_long nop $ nop + +#elif F_CPU == 8000000 + +// 8MHz +#define nop_short nop +#define nop_long nop $ nop $ nop $ nop $ nop + +#elif F_CPU == 16000000 + +// 16MHz +#define nop_short nop $ nop $ nop +#define nop_long nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop + +#else +# error Missing nop definitions for your CPU frequency. +#endif + + +.global led_write_rgb + .type led_write_rgb, @function +; void (uint16_t port, char pins, char r, char g, char b); +; +; Args: +; port: r25, r24 +; pins: r22 +; b: r20 +; g: r19 +; r: r18 +; +; destroys: r19 +; +; The leds expect the data in G-R-B order +led_write_rgb: + clr r0 + dec r0 + + call L_led_write_byte + mov r19, r18 + call L_led_write_byte + mov r19, r20 + call L_led_write_byte + ret + +; Args: +; port: X -- curently ignored, hadcoded to PORTD +; pins: r22 -- currently ignored, hardcoded to 0xFF +; byte: r19 (!) +; +; Prerequisites: +; r0 must be 0xFF +; +; destroys: r21 -- will be 0 afterwards +; destroys: r19 -- call rol on it once to restore +L_led_write_byte: + + ldi r21, 8 + +L_led_write_byte__loop_head: + rol r19 + brcc L_led_write_byte__zero + +L_led_write_byte__one: + out PORTD, r0 + nop_long + out PORTD, r1 + nop_short + rjmp L_led_write_byte__loop_ctrl + +L_led_write_byte__zero: + out PORTD, r0 + nop_short + out PORTD, r1 + nop_long + +L_led_write_byte__loop_ctrl: + ; loop ctrl + dec r21 + brne L_led_write_byte__loop_head + +L_led_write_byte__out: + ret |
