Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 2092 → Rev 2093

/Digital_RGB_LED_Stripes/tags/ws2812b_sample/ws2812b.sx
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