Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Jan Kasprzak
tinyboard
Commits
5013d759
Commit
5013d759
authored
Dec 23, 2013
by
Jan Kasprzak
Browse files
rgb-led-string: christmas tree mode
parent
946b1461
Changes
1
Hide whitespace changes
Inline
Side-by-side
projects/rgb-led-string/main.c
View file @
5013d759
...
...
@@ -4,86 +4,290 @@
#include
"rgbstring.h"
unsigned
char
jiffies
;
static
unsigned
char
jiffies
;
typedef
struct
{
unsigned
char
type
:
4
;
unsigned
char
order
:
4
;
}
pixel_t
;
// #define CHRISTMAS_TREE 1
pixel_t
pixels
[
STRIP_SIZE
];
#define rgb_return(r, g, b) do { send_rgb((r), (g), (b)); return 1; } while(0)
#define VERT_SIZE 47
/* RNG from ADC noise */
static
unsigned
char
rand_pool
[
8
],
rand_pool_off
,
prev_bit
,
rand_pool_out
;
static
void
init_rng
()
{
ADCSRA
|=
_BV
(
ADEN
)
|
_BV
(
ADPS2
)
|
_BV
(
ADPS1
);
// enable, clk/64
ADMUX
=
_BV
(
REFS1
)
|
_BV
(
MUX0
)
|
_BV
(
MUX3
);
// 1.1V, PB5:PB5, gain 20
DIDR0
=
_BV
(
ADC0D
);
ADCSRA
|=
_BV
(
ADIE
)
|
_BV
(
ADSC
);
rand_pool_off
=
0
;
prev_bit
=
0
;
}
static
unsigned
char
rand
()
{
unsigned
char
rv
=
0
;
rv
=
rand_pool
[
rand_pool_out
];
rand_pool_out
++
;
if
(
rand_pool_out
>=
sizeof
(
rand_pool
))
rand_pool_out
=
0
;
return
rv
;
}
ISR
(
ADC_vect
)
{
ADCSRA
|=
_BV
(
ADSC
);
if
((
rand_pool_off
&
1
)
==
0
)
{
// first bit of the pair
prev_bit
=
ADCW
&
1
;
rand_pool_off
++
;
}
else
{
unsigned
char
bit
=
ADCW
&
1
;
if
(
bit
==
prev_bit
)
{
// whitening fail: try again
rand_pool_off
--
;
return
;
}
if
(
bit
)
{
rand_pool
[
rand_pool_off
>>
4
]
^=
1
<<
((
rand_pool_off
>>
1
)
&
7
);
}
rand_pool_off
++
;
if
(
rand_pool_off
>=
16
*
sizeof
(
rand_pool
))
rand_pool_off
=
0
;
}
}
/* up and down running stars at the beginning/end of the strip */
static
unsigned
char
updown_star
,
updown_star0
,
updown_down
,
updown_bright
;
static
void
updown_star_init
()
{
updown_star0
=
0
;
updown_down
=
1
;
}
static
void
updown_star_frame
()
{
if
(
updown_star0
==
0
)
{
updown_star0
=
STRIP_SIZE
-
VERT_SIZE
-
8
;
updown_down
=
0
;
}
else
if
(
updown_star0
==
STRIP_SIZE
+
8
)
{
updown_star0
=
VERT_SIZE
+
7
;
updown_down
=
1
;
}
else
if
(
updown_star0
<=
VERT_SIZE
+
8
)
{
updown_star0
--
;
}
else
if
(
updown_star0
>=
STRIP_SIZE
-
VERT_SIZE
-
8
)
{
updown_star0
++
;
}
if
(
updown_down
&&
updown_star0
<
8
)
{
updown_star
=
0
;
updown_bright
=
1
<<
updown_star0
;
}
else
if
(
updown_down
)
{
updown_star
=
updown_star0
-
8
;
updown_bright
=
128
;
}
else
if
(
updown_star0
<
STRIP_SIZE
-
VERT_SIZE
)
{
updown_star
=
STRIP_SIZE
-
VERT_SIZE
;
updown_bright
=
1
<<
(
STRIP_SIZE
-
VERT_SIZE
-
updown_star0
);
}
else
{
updown_star
=
updown_star0
;
updown_bright
=
1
;
}
}
static
unsigned
char
updown_star_pixel
(
unsigned
char
pos
)
{
if
(
pos
>=
VERT_SIZE
&&
pos
<
STRIP_SIZE
-
VERT_SIZE
)
return
0
;
if
(
pos
==
updown_star
)
{
send_rgb
(
updown_bright
,
updown_bright
,
updown_bright
);
if
(
updown_down
)
{
updown_bright
>>=
1
;
if
(
updown_bright
)
updown_star
++
;
}
else
{
updown_bright
<<=
1
;
if
(
updown_bright
)
updown_star
++
;
}
return
1
;
}
return
0
;
}
/* down running stars at the beginning/end of the strip */
static
unsigned
char
down_star
,
down_star0
,
down_bright
;
static
void
down_star_init
()
{
down_star0
=
STRIP_SIZE
;
}
static
void
down_star_frame
()
{
if
(
down_star0
==
0
)
{
down_star0
=
STRIP_SIZE
;
}
else
{
down_star0
--
;
}
if
(
down_star0
<
8
)
{
down_star
=
0
;
down_bright
=
1
<<
down_star0
;
}
else
{
down_star
=
down_star0
;
down_bright
=
128
;
}
}
static
unsigned
char
down_star_pixel
(
unsigned
char
pos
)
{
if
(
pos
==
down_star
)
{
send_rgb
(
down_bright
,
down_bright
,
down_bright
);
down_bright
>>=
1
;
if
(
down_bright
)
down_star
++
;
return
1
;
}
return
0
;
}
/* middle stars */
static
unsigned
char
midstar_pos0
,
midstar_pos
,
midstar_bright
,
midstar_color
;
static
void
midstar_init
()
{
midstar_pos0
=
STRIP_SIZE
/
2
;
midstar_color
=
0
;
}
static
unsigned
int
slow_dim
[]
=
{
255
,
182
,
130
,
92
,
66
,
47
,
33
,
24
,
17
,
12
,
8
,
6
,
4
,
3
,
2
,
1
,
};
static
void
midstar_frame
()
{
unsigned
char
phase
=
(
jiffies
)
&
0x1F
;
midstar_bright
=
phase
&
0x10
?
slow_dim
[
phase
&
0x0F
]
:
slow_dim
[
15
-
(
phase
&
0x0F
)];
if
(
!
phase
)
{
unsigned
char
c
=
rand
();
#ifdef CHRISTMAS_TREE
midstar_pos0
=
2
+
(
c
%
(
STRIP_SIZE
-
4
));
#else
midstar_pos0
-=
2
+
VERT_SIZE
;
midstar_pos0
+=
16
+
(
c
&
0x1F
);
midstar_pos0
&=
0x3F
;
midstar_pos0
+=
2
+
VERT_SIZE
;
#endif
midstar_color
+=
1
+
(
c
&
0xC0
?
0
:
1
);
}
midstar_pos
=
midstar_pos0
-
2
;
}
static
unsigned
char
midstar_pixel
(
unsigned
char
pos
)
{
unsigned
char
dim
;
if
(
pos
!=
midstar_pos
)
return
0
;
if
(
pos
>
midstar_pos0
)
{
dim
=
pos
-
midstar_pos0
;
if
(
dim
<
2
)
midstar_pos
++
;
}
else
{
dim
=
midstar_pos0
-
pos
;
midstar_pos
++
;
}
dim
=
midstar_bright
>>
2
*
dim
;
if
(
dim
>=
2
)
{
switch
(
midstar_color
&
0x7
)
{
case
0
:
send_rgb
(
dim
,
0
,
0
);
break
;
// red
case
1
:
send_rgb
(
dim
,
dim
,
dim
);
break
;
// white
case
2
:
send_rgb
(
0
,
dim
,
0
);
break
;
// green
case
3
:
send_rgb
(
dim
,
0
,
dim
);
break
;
// violet
case
4
:
send_rgb
(
dim
,
dim
>>
2
,
0
);
break
;
// yellow/orange
case
5
:
send_rgb
(
0
,
dim
,
dim
>>
2
);
break
;
// cyan
case
6
:
send_rgb
(
0
,
0
,
dim
);
break
;
// blue
case
7
:
send_rgb
(
dim
,
dim
,
0
);
break
;
// yellow
}
return
1
;
}
else
{
return
0
;
}
}
static
void
background
(
unsigned
char
pos
)
{
#ifdef CHRISTMAS_TREE
switch
((
pos
>>
4
)
&
3
)
{
case
0
:
if
(
pos
&
1
)
send_rgb
(
7
,
0
,
0
);
else
send_rgb
(
0
,
7
,
0
);
break
;
case
1
:
if
(
pos
&
1
)
send_rgb
(
0
,
0
,
7
);
else
send_rgb
(
7
,
7
,
7
);
break
;
case
2
:
if
(
pos
&
1
)
send_rgb
(
7
,
0
,
7
);
else
send_rgb
(
0
,
7
,
5
);
break
;
case
3
:
if
(
pos
&
1
)
send_rgb
(
7
,
5
,
0
);
else
send_rgb
(
7
,
7
,
7
);
break
;
}
#else
send_rgb
(
0
,
0
,
7
);
#endif
}
int
main
(
void
)
{
unsigned
char
i
,
start
,
rgb
,
jiffies
;
init_log
();
init_rng
();
init_serial
();
_delay_ms
(
3000
/
8
);
_delay_ms
(
3000
/
8
);
// wait for a bit and then increase the CPU clock
CLKPR
=
_BV
(
CLKPCE
);
CLKPR
=
0
;
for
(
i
=
0
;
i
<
STRIP_SIZE
;
i
+=
23
)
pixels
[
i
].
type
=
2
;
sei
();
while
(
1
)
{
jiffies
++
;
if
((
jiffies
&
7
)
==
0
)
{
pixels
[
start
].
type
=
1
;
pixels
[
start
].
order
=
14
;
}
#ifdef CHRISTMAS_TREE
down_star_init
()
;
#else
updown_star_init
()
;
#endif
midstar_init
();
if
((
jiffies
&
7
)
==
3
)
{
pixels
[
start
].
type
=
2
;
pixels
[
start
].
order
=
0
;
start
+=
19
;
}
while
(
1
)
{
unsigned
char
i
;
start
+=
63
;
if
(
start
>=
STRIP_SIZE
)
start
-=
STRIP_SIZE
;
++
jiffies
;
#ifdef CHRISTMAS_TREE
down_star_frame
();
#else
updown_star_frame
();
#endif
midstar_frame
();
for
(
i
=
0
;
i
<
STRIP_SIZE
;
i
++
)
{
unsigned
char
type
=
pixels
[
i
].
type
;
unsigned
char
order
=
pixels
[
i
].
order
;
switch
(
type
)
{
case
0
:
send_rgb
(
0
,
0
,
4
);
break
;
case
1
:
case
3
:
send_rgb
(
6
+
(
1
<<
(
order
/
2
)),
6
+
(
1
<<
(
order
/
2
)),
6
+
(
1
<<
(
order
/
2
))
);
pixels
[
i
].
type
=
type
==
3
?
2
:
0
;;
if
(
order
>
1
&&
i
)
{
pixels
[
i
-
1
].
type
=
pixels
[
i
-
1
].
type
==
2
?
3
:
1
;
pixels
[
i
-
1
].
order
=
order
-
1
;
}
break
;
case
2
:
if
(
order
>=
8
)
{
send_rgb
(
1
<<
((
15
-
order
)
/
2
),
0
,
0
);
}
else
{
send_rgb
(
1
<<
(
order
/
2
),
0
,
0
);
}
if
(
++
order
>=
15
)
pixels
[
i
].
type
=
0
;
pixels
[
i
].
order
=
order
;
break
;
}
#ifdef CHRISTMAS_TREE
if
(
down_star_pixel
(
i
))
continue
;
#else
if
(
updown_star_pixel
(
i
))
continue
;
#endif
if
(
midstar_pixel
(
i
))
continue
;
background
(
i
);
}
end_frame
();
_delay_ms
(
50
);
#if 0
log_byte(0xFa);
log_flush();
#endif
_delay_ms
(
30
);
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment