-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser_2.0.c
246 lines (220 loc) · 7.01 KB
/
user_2.0.c
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/*
* LED-Strip SPI - non-blocking
* Author: Erich Buri <erich.buri@gmail.com>
*
* - Uses different buffers for animator and LED-Strip-Writer
* - Uses common functions for the timer-stuff
*/
#define DEBUG_MODE NODEBUG
#include <stdlib.h>
#include <typedef.h>
#include <system.c>
#include <delay.c>
#include <spi.c>
//////////////////////////////////////////////////////////////////////////////////
// TYPES
//////////////////////////////////////////////////////////////////////////////////
typedef struct _timerContext {
u32 timer_start; // us-counter-start
u32 timer_stop; // us-counter-stop
u32 timer_delay; // ms-delay
} timerContext;
//////////////////////////////////////////////////////////////////////////////////
// CONSTS & VARIABLES
//////////////////////////////////////////////////////////////////////////////////
// Common
#define LEDS 32 * 20
u8 Fcp0; // number of GetCP0Count()'s for one microsecond
u8 pixel_buff_one[LEDS * 3]; // Two buffer's. One of them is currently drawn,
u8 pixel_buff_two[LEDS * 3]; // the other can be edited
// LED Blinker
#define LB_LED_PIN 13
#define LB_S_WAIT_HIGH 1
#define LB_S_WAIT_LOW 2
u8 lb_state; // LED_Blinker state - to show non-blocking I/O
timerContext lb_timer; // Timer variables for the LED_Blinker
// LED-Strip Writer variables
#define LW_S_WAIT_TO_WRITE_PIXEL 1
#define LW_S_WAIT_TO_WRITE_ZEROS 2
#define LW_ZEROS_NEEDED (3 * ((LEDS + 63) / 64))
u8 lw_state; // This is the state of the LED_Writer State-machine
u8 *lw_buffer; // Pointer to the buffer that the LED_Writer should draw
u32 lw_pixelIndex; // current Pixel
u8 lw_zeroCounter; // counter for zeros to send at the end
// Animator variables
#define ANIM_S_WAIT_EVEN 1
#define ANIM_S_WAIT_ODD 2
#define ON_COLOR_R 0x00
#define ON_COLOR_G 0x00
#define ON_COLOR_B 0xFF
#define OFF_COLOR_R 0x00
#define OFF_COLOR_G 0x00
#define OFF_COLOR_B 0x00
u8 *pixels; // Pointer to the buffer were the Animator can work
u8 anim_state; // Animator state - to show non-blocking I/O
timerContext dataLink_timer;// Timer variables for the Animator
//////////////////////////////////////////////////////////////////////////////////
// Timer and other general functions
//////////////////////////////////////////////////////////////////////////////////
void reset_us_timer(timerContext *timer) {
timer->timer_start = GetCP0Count();
timer->timer_stop = timer->timer_start + 1000 * Fcp0;
}
void start_ms_timer(timerContext *timer, u32 msDelay) {
// set ms-delay to <delay>
timer->timer_delay = msDelay;
reset_us_timer(timer);
}
// check counter. If us-delay is up, decrement ms-delay
// return 1, if time is up, 0, if timer still running
u8 check_timer(timerContext *timer) {
if(timer->timer_start < timer->timer_stop) {
// "normal" case, just wait until GetCP0Count > lb_timer_stop
if(GetCP0Count() > timer->timer_stop) {
// us timer is up, reset
reset_us_timer(timer);
if( --(timer->timer_delay) <= 0 )
return 1;
}
} else {
// "overflow" case, wait until count is smaller then start
// (=> count did the overflow, too) and then until count > stop
if( GetCP0Count() < timer->timer_start && GetCP0Count() > timer->timer_stop ) {
// us timer is up, reset
reset_us_timer(timer);
if( --(timer->timer_delay) <= 0 )
return 1;
}
}
return 0;
}
void switch_buffers() {
if(lw_buffer == pixel_buff_one) {
lw_buffer = pixel_buff_two;
pixels = pixel_buff_one;
} else {
lw_buffer = pixel_buff_one;
pixels = pixel_buff_two;
}
}
//////////////////////////////////////////////////////////////////////////////////
// LED Blinker
//////////////////////////////////////////////////////////////////////////////////
void lb_setup() {
// LED_Blinker setup
pinmode(LB_LED_PIN,OUTPUT);
lb_state = LB_S_WAIT_HIGH;
start_ms_timer(&lb_timer, 1000);
}
void lb_process() {
if(lb_state == LB_S_WAIT_HIGH && check_timer(&lb_timer)) {
// Waiting to go high, and timer is up
digitalwrite(LB_LED_PIN, HIGH);
start_ms_timer(&lb_timer, 1000);
lb_state = LB_S_WAIT_LOW;
}
if(lb_state == LB_S_WAIT_LOW && check_timer(&lb_timer)) {
// Waiting to go high, and timer is up
digitalwrite(LB_LED_PIN, LOW);
start_ms_timer(&lb_timer, 500);
lb_state = LB_S_WAIT_HIGH;
}
}
//////////////////////////////////////////////////////////////////////////////////
// LED-Strip Writer
//////////////////////////////////////////////////////////////////////////////////
void lw_setup() {
// start by writting zeros to wake-up latch(s)
lw_state = LW_S_WAIT_TO_WRITE_ZEROS;
lw_pixelIndex = 0;
lw_zeroCounter = LW_ZEROS_NEEDED;
SPI_init();
/* 10mhz - faster is not working */
SPI_clock(GetSystemClock() / SPI_PBCLOCK_DIV8);
SPI_mode(SPI_MASTER);
BUFFER = 0x00; // Trigger STATRX
}
void lw_process() {
if(lw_state == LW_S_WAIT_TO_WRITE_PIXEL && (STATRX)) {
// ready to write a pixel
BUFFER = (0x80 | lw_buffer[lw_pixelIndex++]);
if(lw_pixelIndex >= (LEDS * 3)) {
// sent'em all
lw_state = LW_S_WAIT_TO_WRITE_ZEROS;
lw_zeroCounter = LW_ZEROS_NEEDED;
}
}
if(lw_state == LW_S_WAIT_TO_WRITE_ZEROS && (STATRX)) {
// ready to write a zero
BUFFER = 0x00;
if(--lw_zeroCounter <= 0) {
// done with zeros, write pixels
lw_state = LW_S_WAIT_TO_WRITE_PIXEL;
lw_pixelIndex = 0;
}
}
}
//////////////////////////////////////////////////////////////////////////////////
// Animator
//////////////////////////////////////////////////////////////////////////////////
void dataLink_setup() {
anim_state = ANIM_S_WAIT_EVEN;
start_ms_timer(&dataLink_timer, 50);
}
void dataLink_process() {
u32 i;
if(anim_state == ANIM_S_WAIT_EVEN && check_timer(&dataLink_timer)) {
// Waiting to light up EVEN
for(i=0; i < LEDS; i++) {
u32 lidx = i*3;
// if( (i % 2) == 0) {
pixels[lidx] = ON_COLOR_G;
pixels[lidx + 1] = ON_COLOR_R;
pixels[lidx + 2] = ON_COLOR_B;
// } else {
// pixels[lidx] = OFF_COLOR_G;
// pixels[lidx + 1] = OFF_COLOR_R;
// pixels[lidx + 2] = OFF_COLOR_B;
// }
}
switch_buffers();
start_ms_timer(&dataLink_timer, 1000);
anim_state = ANIM_S_WAIT_ODD;
}
if(anim_state == ANIM_S_WAIT_ODD && check_timer(&dataLink_timer)) {
// Waiting to light up ODD
for(i=0; i < LEDS; i++) {
u32 lidx = i*3;
// if( (i % 2) == 0) {
pixels[lidx] = OFF_COLOR_G;
pixels[lidx + 1] = OFF_COLOR_R;
pixels[lidx + 2] = OFF_COLOR_B;
// } else {
// pixels[lidx] = ON_COLOR_G;
// pixels[lidx + 1] = ON_COLOR_R;
// pixels[lidx + 2] = ON_COLOR_B;
// }
}
switch_buffers();
start_ms_timer(&dataLink_timer, 1000);
anim_state = ANIM_S_WAIT_EVEN;
}
}
//////////////////////////////////////////////////////////////////////////////////
// MAIN Setup & process
//////////////////////////////////////////////////////////////////////////////////
void setup() {
// for delays - CP0Count counts at half the CPU rate
Fcp0 = GetSystemClock() / 1000000 / 2; // max = 40 for 80MHz
// setup-buffers
lw_buffer = pixel_buff_one;
pixels = pixel_buff_two;
//lb_setup();
lw_setup();
dataLink_setup();
}
void loop() {
//lb_process();
lw_process();
dataLink_process();
}