Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 1882 → Rev 2093

/Digital_RGB_LED_Stripes/tags/ws2812b_sample/ws2812b.sx
New file
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
/Digital_RGB_LED_Stripes/tags/ws2812b_sample/sample.c
New file
0,0 → 1,67
///////////////////////////////////////////////////////////////////////////////
 
#define RIGGER_CNT 4 // up to 8
#define LED_CNT 10
#define LED_BIT_CNT 3 * LED_CNT * 8 // RGB * LED_CNT * Bits_per_led
#define LED_BIT_INDEX(led, color, bit) (led * 24 + color * 8 + 7 - bit)
 
///////////////////////////////////////////////////////////////////////////////
//
// One bit per channel, 8 bytes per color, 3 colors per pixel
//
// Pixel_1
// Green Red Blue
// 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
// Channel_0
// Channel_1
// Channel_2
// Channel_3
// Channel_4
// Channel_5
// Channel_6
// Channel_7
//
///////////////////////////////////////////////////////////////////////////////
 
typedef unsigned char Data[LED_BIT_CNT];
 
///////////////////////////////////////////////////////////////////////////////
 
#include <util/delay.h>
#include "ws2812b.h"
 
///////////////////////////////////////////////////////////////////////////////
//
// One Channel per Port bit, up to eight channels
//
///////////////////////////////////////////////////////////////////////////////
 
void sample(double delay)
{
Data data;
unsigned char l;
 
for(l=0;l<2;l++)
{
unsigned char k=l;
unsigned short i=0;
 
while(i<sizeof(data))
{
unsigned char b;
unsigned char d;
d = (k & 1)?0x05:0x04;
for(b=0;b<8;b++)data[i++] = d; // Green
d = (k & 1)?0x09:0x08;
for(b=0;b<8;b++)data[i++] = d; // Red
d = (k & 1)?0x03:0x02;
for(b=0;b<8;b++)data[i++] = d; // Blue
k++;
}
ws2812b_send(data, sizeof(data));
_delay_ms(delay);
}
}
 
///////////////////////////////////////////////////////////////////////////////
/Digital_RGB_LED_Stripes/tags/ws2812b_sample/ws2812b.h
New file
0,0 → 1,13
#pragma once
 
///////////////////////////////////////////////////////////////////////////////
 
#include "defines.h"
 
///////////////////////////////////////////////////////////////////////////////
 
void ws2812b_send(U8 * data, U16 n);
void ws2812b_send_p(const U8 * data, U16 n);
///////////////////////////////////////////////////////////////////////////////