Subversion Repositories Projects

Rev

Blame | Last modification | View Log | RSS feed

///////////////////////////////////////////////////////////////////////////////
//
// 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