-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRainbowduino.cpp
executable file
·140 lines (122 loc) · 4.21 KB
/
Rainbowduino.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
* Rainbowduino.h version 3.0beta - A driver to run Seeedstudio 8x8 RBG LED Matrix
* Copyright (c) 2013 Tobias Bielohlawek -> http://www.rngtng.com
*
*/
// include this library's description file
#include "Rainbowduino.h"
// Constructor /////////////////////////////////////////////////////////////////
// Function that handles the creation and setup of instances
Rainbowduino::Rainbowduino() {
DDRD = 0xff;
DDRC = 0xff;
DDRB = 0xff;
PORTB = 0;
PORTD = 0;
reset();
}
//=== Frame Show Manipulating ==========================================================
void Rainbowduino::reset() {
current_frame_nr = 0;
current_row = 0;
current_level = 0;
current_frame_offset = 0;
num_frames = 0;
}
uint8_t Rainbowduino::get_num_frames() {
return num_frames;
}
void Rainbowduino::set_current_frame_nr(uint8_t frame_nr) {
if(frame_nr < num_frames) current_frame_nr = frame_nr;
}
uint8_t Rainbowduino::get_current_frame_nr() {
return current_frame_nr;
}
void Rainbowduino::next_frame() {
current_frame_nr++;
if(current_frame_nr >= num_frames) current_frame_nr = 0;
}
//=== Frame Data Manipulating ==========================================================
void Rainbowduino::set_frame(uint8_t frame_nr, uint8_t* data) {
if(frame_nr >= MAX_NUM_FRAMES) return;
word offset = frame_nr * NUM_ROWS;
for(uint8_t row = 0; row < NUM_ROWS; row++) {
frame_buffer[offset+row] = data[row];
}
if(frame_nr >= num_frames) num_frames = frame_nr + 1;
}
void Rainbowduino::set_frame_row(uint8_t frame_nr, uint8_t row, uint8_t data) {
if(frame_nr >= MAX_NUM_FRAMES) return;
word offset = frame_nr * NUM_ROWS;
frame_buffer[offset+row] = data;
if(frame_nr >= num_frames) num_frames = frame_nr + 1;
}
uint8_t Rainbowduino::get_frame_row(uint8_t frame_nr, uint8_t row) {
if(frame_nr >= num_frames) return 0;
word offset = frame_nr * NUM_ROWS;
return frame_buffer[offset+row];
}
void Rainbowduino::set_frame_line(uint8_t frame_nr, uint8_t x, uint8_t red, uint8_t green, uint8_t blue) {
if(frame_nr >= MAX_NUM_FRAMES) return;
word offset = frame_nr * NUM_ROWS + x * 3;
frame_buffer[offset] = red;
frame_buffer[offset+1] = green;
frame_buffer[offset+2] = blue;
if(frame_nr >= num_frames) num_frames = frame_nr + 1;
}
void Rainbowduino::set_frame_pixel(uint8_t frame_nr, uint8_t x, uint8_t y, uint8_t red, uint8_t green, uint8_t blue) {
if(frame_nr >= MAX_NUM_FRAMES) return;
word offset = frame_nr * NUM_ROWS + x * 3;
frame_buffer[offset] = (red > 0) ? frame_buffer[offset] | (1<<y) : frame_buffer[offset] & ~(1<<y);
frame_buffer[offset+1] = (green > 0) ? frame_buffer[offset+1] | (1<<y) : frame_buffer[offset+1] & ~(1<<y);
frame_buffer[offset+2] = (blue > 0) ? frame_buffer[offset+2] | (1<<y) : frame_buffer[offset+2] & ~(1<<y);
if(frame_nr >= num_frames) num_frames = frame_nr + 1;
}
//=== Drawing ===========================================================
void Rainbowduino::draw(uint8_t level) {
if(num_frames == 0) return; //no frames available
off = current_frame_nr * NUM_ROWS + current_row;
draw_row(current_row / 3, level, frame_buffer[off++], frame_buffer[off++], frame_buffer[off++]);
if(current_row >= NUM_ROWS - 1) {
current_row = 0;
current_level = (current_level >= NUM_LEVEL - 1) ? 0 : current_level+1;
}
else {
current_row = current_row + 3;
}
}
//--- colors to shift: blue, red, green
void Rainbowduino::draw_row(uint8_t row, uint8_t level, uint8_t r, uint8_t g, uint8_t b) {
disable_oe;
enable_row(row);
le_high;
draw_color( (current_level < level) ? b : 0 );
draw_color( (current_level < level) ? r : 0 );
draw_color( (current_level < level) ? g : 0 );
le_low;
enable_oe;
}
void Rainbowduino::draw_color(uint8_t c) {
for(uint8_t color = 0; color < 8; color++) {
if((c & 1) == 1) {
shift_data_1;
}
else {
shift_data_0;
}
c = c >> 1;
clk_rising;
}
}
//==============================================================
void Rainbowduino::enable_row(uint8_t row) { // open the scaning row
//better? shift word value, take upper and lower part!?
if(row < 3) {
PORTB = (PINB & ~0x07) | 0x04 >> row;
PORTD = (PIND & ~0xF8);
}
else {
PORTB = (PINB & ~0x07);
PORTD = (PIND & ~0xF8) | 0x80 >> (row - 3);
}
}