0,0 → 1,328 |
/////////////////////////////////////////////////////////////////////////////// |
// |
// 16MHz |
// |
/////////////////////////////////////////////////////////////////////////////// |
#if F_CPU == 16000000UL |
/////////////////////////////////////////////////////////////////////// |
|
.file "ws2812b.sx" |
|
__SREG__ = 0x3f |
__SP_H__ = 0x3e |
__SP_L__ = 0x3d |
__CCP__ = 0x34 |
__tmp_reg__ = 0 |
__zero_reg__ = 1 |
|
.text |
|
/////////////////////////////////////////////////////////////////////// |
// |
// ws2812b_send(U8 * ptr, U16 cnt) |
// |
// H H H H H H d d d d d d d L L L L L L L |
// ^ ^ ^ ^ ^ ^ |
// 1 6 7 13 14 20 |
// |
// 20 cyles @ 62.5ns(16MHz) = 1.25us |
// |
/////////////////////////////////////////////////////////////////////// |
|
.global ws2812b_send |
.type ws2812b_send, @function |
|
/////////////////////////////////////////////////////////////////////// |
|
ws2812b_send: |
movw r30,r24 // 1 U8 *ptr |
movw r26,r22 // 1 U16 cnt |
|
ldi r25,lo8(0) // 1 Low |
ldi r24,lo8(-1) // 1 High |
|
ld r18,Z+ // 2 data = *ptr++ |
cli |
|
//////////////////////////////////////////////////////////////////////// |
|
bit_loop: // (T = 0) |
|
// High //////////////////////////////////////////////////////////////// |
|
out 11, r24 // 1 high (T = 1) |
rjmp .+0 // 2 nop nop (T = 3) |
rjmp .+0 // 2 nop nop (T = 5) |
nop // 1 nop (T = 6) |
|
// Data //////////////////////////////////////////////////////////////// |
|
out 11, r18 // 1 data (T = 7) |
rjmp .+0 // 2 nop nop (T = 9) |
rjmp .+0 // 2 nop nop (T = 11) |
rjmp .+0 // 2 nop nop (T = 13) |
|
// Low ///////////////////////////////////////////////////////////////// |
|
out 11, r25 // 1 low (T = 14) |
ld r18 , Z+ // 2 data = *ptr++ (T = 16) |
|
// cnt-- /////////////////////////////////////////////////////////////// |
|
sbiw r26, 1 // 2 cnt-- (T = 18) |
brne bit_loop // 2 if(count!=0) branch (T = 20) |
|
//////////////////////////////////////////////////////////////////////// |
// |
// _delay_us(50) := 200 * 4 * 62.5ns @ 16MHz |
// |
//////////////////////////////////////////////////////////////////////// |
|
ldi r24,lo8(200) // 1 delay_cnt = 200; |
ldi r25,hi8(200) // 1 |
|
/////////////////////////////////////////////////////////////////////// |
|
delay: sbiw r24,1 // 2 delay-- |
brne delay // 2 if(delay_cnt!=0) branch |
|
//////////////////////////////////////////////////////////////////////// |
|
sei |
ret // 4/5 |
|
//////////////////////////////////////////////////////////////////////// |
|
.size ws2812b_send, .-ws2812b_send |
|
///////////////////////////////////////////////////////////////////////// |
// |
// ws2812b_send_p(U8 * ptr progmen, U16 cnt) |
// |
// H H H H H H d d d d d d d L L L L L L L |
// ^ ^ ^ ^ ^ ^ |
// 1 6 7 13 14 20 |
// |
// 20 cyles @ 62.5ns(16MHz) = 1.25us |
// |
///////////////////////////////////////////////////////////////////////// |
|
.global ws2812b_send_p |
.type ws2812b_send_p, @function |
|
///////////////////////////////////////////////////////////////////////// |
|
ws2812b_send_p: |
movw r30,r24 // 1 U8 *ptr |
movw r26,r22 // 1 U16 cnt |
|
ldi r25,lo8(0) // 1 Low |
ldi r24,lo8(-1) // 1 High |
|
lpm r18,Z+ // 3 data = ptr++ |
cli |
|
///////////////////////////////////////////////////////////////////////// |
|
bit_loop_p: // (T = 0) |
|
// High //////////////////////////////////////////////////////////////// |
|
out 11, r24 // 1 high (T = 1) |
rjmp .+0 // 2 nop nop (T = 3) |
rjmp .+0 // 2 nop nop (T = 5) |
nop // 1 nop (T = 6) |
|
// Data //////////////////////////////////////////////////////////////// |
|
out 11, r18 // 1 data (T = 7) |
lpm r18 , Z+ // 3 data = *ptr++ (T = 10) |
rjmp .+0 // 2 nop nop (T = 12) |
nop // 1 nop (T = 13) |
|
// Low ///////////////////////////////////////////////////////////////// |
|
out 11, r25 // 1 low (T = 14) |
rjmp .+0 // 2 nop nop (T = 16) |
|
// cnt-- /////////////////////////////////////////////////////////////// |
|
sbiw r26, 1 // 2 cnt-- (T = 18) |
brne bit_loop_p // 2 if(count!=0) branch (T = 20) |
|
//////////////////////////////////////////////////////////////////////// |
// |
// _delay_us(50) := 200 * 4 * 62.5ns @ 16MHz |
// |
//////////////////////////////////////////////////////////////////////// |
|
ldi r24,lo8(200) // delay_cnt = 200; |
ldi r25,hi8(200) // |
|
/////////////////////////////////////////////////////////////////////// |
|
delayP: sbiw r24,1 // 2 delay-- |
brne delayP // 2 if(delay_cnt!=0) branch |
|
//////////////////////////////////////////////////////////////////////// |
|
sei |
ret // 4/5 |
|
//////////////////////////////////////////////////////////////////////// |
|
.size ws2812b_send_p, .-ws2812b_send_p |
|
/////////////////////////////////////////////////////////////////////// |
#endif |
|
/////////////////////////////////////////////////////////////////////////////// |
// |
// 8MHz |
// |
/////////////////////////////////////////////////////////////////////////////// |
|
#if F_CPU == 8000000UL |
|
/////////////////////////////////////////////////////////////////////// |
// |
// ws2812b_send(U8 * ptr, U16 cnt) |
// |
// H H H d d d L L L L |
// ^ ^ ^ ^ ^ ^ |
// 1 3 4 6 7 10 |
// |
// 10 cyles @ 125ns(8MHz) = 1.25us |
// |
/////////////////////////////////////////////////////////////////////// |
|
.global ws2812b_send |
.type ws2812b_send, @function |
|
/////////////////////////////////////////////////////////////////////// |
|
ws2812b_send: |
movw r30,r24 // 1 U8 *ptr |
movw r26,r22 // 1 U16 cnt |
|
ldi r25,lo8(0) // 1 Low |
ldi r24,lo8(-1) // 1 High |
|
ld r18,Z+ // 2 data = *ptr++ |
cli |
|
//////////////////////////////////////////////////////////////////////// |
|
bit_loop: // (T = 0) |
|
// High //////////////////////////////////////////////////////////////// |
|
out 11, r24 // 1 high (T = 1) |
sbiw r26, 1 // 2 cnt-- (T = 3) |
|
// Data //////////////////////////////////////////////////////////////// |
|
out 11, r18 // 1 data (T = 4) |
ld r18 , Z+ // 2 data = *ptr++ (T = 6) |
nop // 1 nop (T = 7) |
|
// Low ///////////////////////////////////////////////////////////////// |
|
out 11, r25 // 1 low (T = 8) |
brne bit_loop // 2 if(count!=0) branch (T = 10) |
|
//////////////////////////////////////////////////////////////////////// |
// |
// _delay_us(50) := 100 * 4 * 125ns @ 8MHz |
// |
//////////////////////////////////////////////////////////////////////// |
|
ldi r24,lo8(100) // 1 delay_cnt = 100; |
ldi r25,hi8(100) // 1 |
|
/////////////////////////////////////////////////////////////////////// |
|
delay: sbiw r24,1 // 2 delay-- |
brne delay // 2 if(delay_cnt!=0) branch |
|
//////////////////////////////////////////////////////////////////////// |
|
sei |
ret // 4/5 |
|
//////////////////////////////////////////////////////////////////////// |
|
.size ws2812b_send, .-ws2812b_send |
|
/////////////////////////////////////////////////////////////////////// |
// |
// ws2812b_send_p(U8 * ptr, U16 cnt) |
// |
// H H H d d d L L L L |
// ^ ^ ^ ^ ^ ^ |
// 1 3 4 6 7 10 |
// |
// 10 cyles @ 125ns(8MHz) = 1.25us |
// |
/////////////////////////////////////////////////////////////////////// |
|
.global ws2812b_send_p |
.type ws2812b_send_p, @function |
|
/////////////////////////////////////////////////////////////////////// |
|
ws2812b_send_p: |
movw r30,r24 // 1 U8 *ptr |
movw r26,r22 // 1 U16 cnt |
|
ldi r25,lo8(0) // 1 Low |
ldi r24,lo8(-1) // 1 High |
|
lpm r18,Z+ // 2 data = *ptr++ |
cli |
|
//////////////////////////////////////////////////////////////////////// |
|
bit_loop_p: // (T = 0) |
|
// High //////////////////////////////////////////////////////////////// |
|
out 11, r24 // 1 high (T = 1) |
sbiw r26, 1 // 2 cnt-- (T = 3) |
|
// Data //////////////////////////////////////////////////////////////// |
|
out 11, r18 // 1 data (T = 4) |
lpm r18, Z+ // 3 data = *ptr++ (T = 7) |
|
|
// Low ///////////////////////////////////////////////////////////////// |
|
out 11, r25 // 1 low (T = 8) |
brne bit_loop_p // 2 if(count!=0) branch (T = 10) |
|
//////////////////////////////////////////////////////////////////////// |
// |
// _delay_us(50) := 100 * 4 * 125ns @ 8MHz |
// |
//////////////////////////////////////////////////////////////////////// |
|
ldi r24,lo8(100) // 1 delay_cnt = 100; |
ldi r25,hi8(100) // 1 |
|
/////////////////////////////////////////////////////////////////////// |
|
delay_p: sbiw r24,1 // 2 delay-- |
brne delay_p // 2 if(delay_cnt!=0) branch |
|
//////////////////////////////////////////////////////////////////////// |
|
sei |
ret // 4/5 |
|
//////////////////////////////////////////////////////////////////////// |
|
.size ws2812b_send_p, .-ws2812b_send_p |
|
//////////////////////////////////////////////////////////////////////// |
#endif |