Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
199 Kevin 1
#include "defines.h"
2
#include "CUBE.h"
3
#include "SPI1.h"
206 Kevin 4
#include "glcdfont.h"
213 Kevin 5
#include "UART1.h"
255 Kevin 6
#include "ETHERNET.h"
264 Kevin 7
#include "TIMER4.h"
199 Kevin 8
 
9
static CUBE_DATA *cube_data_ptr;
10
 
11
inline void Cube_Delay() {
12
    // Small delay to ensure that latch speeds are < 30Mhz
13
    Nop();
14
    Nop();
15
    Nop();
16
}
17
 
231 Kevin 18
void Cube_Init(CUBE_DATA *data, uint8_t BC) {
199 Kevin 19
    cube_data_ptr = data;
201 Kevin 20
    cube_data_ptr->current_layer = 0;
205 Kevin 21
    cube_data_ptr->rotation_counter = 0;
212 Kevin 22
    cube_data_ptr->frame_state = IDLE;
23
    cube_data_ptr->frame_escape = 0;
199 Kevin 24
 
25
    SFT_D = 0;
26
    SFT_S = 0;
27
    SFT_K = 0;
28
    SFT_R = 0;
29
    GSLAT = 0;
30
    XBLNK = 0;
31
 
32
    SFT_D_TRIS = 0;
33
    SFT_S_TRIS = 0;
34
    SFT_K_TRIS = 0;
35
    SFT_R_TRIS = 0;
36
    GSLAT_TRIS = 0;
37
    XBLNK_TRIS = 0;
38
 
39
    // Clear the shift register
40
    Cube_Delay();
41
    SFT_K = 1;
42
    Cube_Delay();
43
    SFT_K = 0;
44
    Cube_Delay();
45
    SFT_S = 1;
46
    Cube_Delay();
47
    SFT_S = 0;
48
    Cube_Delay();
49
    SFT_R = 1;
50
 
200 Kevin 51
    Cube_Write_DCS(BC);
199 Kevin 52
    Cube_Clear();
206 Kevin 53
    Cube_Overlay_Clear();
199 Kevin 54
}
55
 
56
void Cube_Timer_Interrupt(void) {
206 Kevin 57
    // OR values in the overlay array with the display array
231 Kevin 58
    uint8_t i;
59
    uint16_t j;
206 Kevin 60
    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
61
        for (j = 0; j < GCS_LAYER_SIZE; j++) {
62
            cube_data_ptr->GCS_WRITE[i][j] = cube_data_ptr->GCS[i][j] | cube_data_ptr->GCS_OVERLAY[i][j];
63
        }
64
    }
199 Kevin 65
    // Write to the GCS register
206 Kevin 66
    SPI1_Write(cube_data_ptr->GCS_WRITE[cube_data_ptr->current_layer], GCS_LAYER_SIZE, &Cube_GCS_Write_Callback);
199 Kevin 67
}
68
 
212 Kevin 69
////////////////////////
70
// Callback functions //
71
////////////////////////
72
 
199 Kevin 73
void Cube_DCS_Write_Callback(void) {
74
    // GSLAT must be >7ms after DCS write
75
    Delay_MS(7);
76
    GSLAT = 0;
77
    Cube_Delay();
78
    GSLAT = 1;
79
    Cube_Delay();
80
    GSLAT = 0;
81
}
82
 
83
void Cube_GCS_Write_Callback(void) {
84
    // Disable LED output and latch in written data to GCS
85
    XBLNK = 0;
86
    Cube_Delay();
87
    GSLAT = 1;
88
    // Set the shift register to turn on the current layer
231 Kevin 89
    uint8_t i;
199 Kevin 90
    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
91
        Cube_Delay();
201 Kevin 92
        SFT_D = (i == CUBE_LAYER_COUNT - cube_data_ptr->current_layer - 1) ? 1 : 0;
199 Kevin 93
        Cube_Delay();
94
        SFT_K = 1;
95
        Cube_Delay();
96
        SFT_K = 0;
97
    }
98
    Cube_Delay();
99
    SFT_S = 1;
100
    Cube_Delay();
101
    SFT_S = 0;
102
    Cube_Delay();
103
    // Enable LED output
104
    XBLNK = 1;
105
    Cube_Delay();
106
    GSLAT = 0;
107
 
201 Kevin 108
    cube_data_ptr->current_layer = (cube_data_ptr->current_layer == CUBE_LAYER_COUNT-1)
109
            ? 0 : cube_data_ptr->current_layer + 1;
199 Kevin 110
}
111
 
212 Kevin 112
////////////////////////////
113
// Cube control functions //
114
////////////////////////////
115
 
231 Kevin 116
void Cube_Write_DCS(uint8_t BC) {
200 Kevin 117
    XBLNK = 0;
231 Kevin 118
    uint8_t i,j;
200 Kevin 119
    // Write configuration data to the DC/BC/FC/UD registers
231 Kevin 120
    uint8_t DCS[GCS_LAYER_SIZE] = {0};
263 Kevin 121
 
200 Kevin 122
    for (i = 0; i < 8; i++) {
231 Kevin 123
        uint16_t offset = i * GCS_REG_SIZE;
200 Kevin 124
 
125
        for (j = 0; j < 21; j++) {
126
            DCS[offset + j] = 0xFF; // Dot correction
127
        }
128
 
263 Kevin 129
        // Warning: do not set BC > 0x6F ?? NEED TO VERIFY THIS !!
200 Kevin 130
        DCS[offset + 21] = BC; // Global red brightness
131
        DCS[offset + 22] = BC; // Global green brightness
132
        DCS[offset + 23] = BC; // Global blue brightness
133
 
134
        // DC low range, auto repeat, no timing reset, 8 bit counter mode
135
        DCS[offset + 24] = 0x68; // 0110 1000
136
    }
137
 
138
    GSLAT = 1;
139
    SPI1_Write(DCS, GCS_LAYER_SIZE, &Cube_DCS_Write_Callback);
201 Kevin 140
    Delay_MS(10); // Delay until the entire DCS write is finished
200 Kevin 141
}
142
 
199 Kevin 143
void Cube_Clear(void) {
231 Kevin 144
    uint8_t i;
145
    uint16_t j;
199 Kevin 146
    for (i = 0; i < CUBE_LAYER_COUNT; i++)
147
        for (j = 0; j < GCS_LAYER_SIZE; j++)
148
            cube_data_ptr->GCS[i][j] = 0x00;
149
}
150
 
231 Kevin 151
void Cube_Set_All(uint16_t R, uint16_t G, uint16_t B) {
201 Kevin 152
    // Set all pixels in the cube to the given color
199 Kevin 153
    R &= 0x0FFF;
154
    G &= 0x0FFF;
155
    B &= 0x0FFF;
231 Kevin 156
    uint8_t i,j,k;
199 Kevin 157
    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
158
        for (j = 0; j < CUBE_ROW_COUNT; j++) {
231 Kevin 159
            uint16_t j_var = j * GCS_REG_SIZE;
199 Kevin 160
            for (k = 0; k < 4; k++) {
231 Kevin 161
                uint16_t k_var = j_var + (k * 9);
199 Kevin 162
                cube_data_ptr->GCS[i][k_var+0] = R & 0xFF;;
163
                cube_data_ptr->GCS[i][k_var+1] = (G << 4) | (R >> 8);
164
                cube_data_ptr->GCS[i][k_var+2] = G >> 4;
165
                cube_data_ptr->GCS[i][k_var+3] = B & 0xFF;
166
                cube_data_ptr->GCS[i][k_var+4] = (R << 4) | (B >> 8);
167
                cube_data_ptr->GCS[i][k_var+5] = R >> 4;
168
                cube_data_ptr->GCS[i][k_var+6] = G & 0xFF;
169
                cube_data_ptr->GCS[i][k_var+7] = (B << 4) | (G >> 8);
170
                cube_data_ptr->GCS[i][k_var+8] = B >> 4;
171
            }
172
        }
173
    }
174
}
175
 
231 Kevin 176
void Cube_Set_Layer(uint8_t layer, uint16_t R, uint16_t G, uint16_t B) {
201 Kevin 177
    // Set all pixels in the specified layer to the given color
199 Kevin 178
    R &= 0x0FFF;
179
    G &= 0x0FFF;
180
    B &= 0x0FFF;
231 Kevin 181
    uint8_t i,j;
199 Kevin 182
    for (i = 0; i < CUBE_ROW_COUNT; i++) {
231 Kevin 183
        uint16_t i_var = i * GCS_REG_SIZE;
199 Kevin 184
        for (j = 0; j < 4; j++) {
231 Kevin 185
            uint16_t j_var = i_var + (j * 9);
199 Kevin 186
            cube_data_ptr->GCS[layer][j_var+0] = R & 0xFF;;
187
            cube_data_ptr->GCS[layer][j_var+1] = (G << 4) | (R >> 8);
188
            cube_data_ptr->GCS[layer][j_var+2] = G >> 4;
189
            cube_data_ptr->GCS[layer][j_var+3] = B & 0xFF;
190
            cube_data_ptr->GCS[layer][j_var+4] = (R << 4) | (B >> 8);
191
            cube_data_ptr->GCS[layer][j_var+5] = R >> 4;
192
            cube_data_ptr->GCS[layer][j_var+6] = G & 0xFF;
193
            cube_data_ptr->GCS[layer][j_var+7] = (B << 4) | (G >> 8);
194
            cube_data_ptr->GCS[layer][j_var+8] = B >> 4;
195
        }
196
    }
197
}
198
 
264 Kevin 199
void Cube_Set_Row(uint8_t row, uint16_t R, uint16_t G, uint16_t B) {
200
    // Set the specified row to the given color
201
    R &= 0x0FFF;
202
    G &= 0x0FFF;
203
    B &= 0x0FFF;
204
    uint8_t column, layer;
205
    for (layer = 0; layer < CUBE_LAYER_COUNT; layer++) {
206
        for (column = 0; column < CUBE_COLUMN_COUNT; column++) {
207
            uint16_t var = row * GCS_REG_SIZE + (column / 2 * 9);
208
            switch (column % 2) {
209
                case 0:
210
                    cube_data_ptr->GCS[layer][var+0] = R & 0xFF;
211
                    cube_data_ptr->GCS[layer][var+1] = (G << 4) | (R >> 8);
212
                    cube_data_ptr->GCS[layer][var+2] = G >> 4;
213
                    cube_data_ptr->GCS[layer][var+3] = B & 0xFF;
214
                    cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0xF0) | (B >> 8);
215
                    break;
216
                case 1:
217
                    cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0x0F) | (R << 4);
218
                    cube_data_ptr->GCS[layer][var+5] = R >> 4;
219
                    cube_data_ptr->GCS[layer][var+6] = G & 0xFF;
220
                    cube_data_ptr->GCS[layer][var+7] = (B << 4) | (G >> 8);
221
                    cube_data_ptr->GCS[layer][var+8] = B >> 4;
222
                    break;
223
            }       
224
        }
225
    }
226
}
227
 
228
void Cube_Set_Column(uint8_t column, uint16_t R, uint16_t G, uint16_t B) {
229
    // Set the specified row to the given color
230
    R &= 0x0FFF;
231
    G &= 0x0FFF;
232
    B &= 0x0FFF;
233
    uint8_t row, layer;
234
    for (layer = 0; layer < CUBE_LAYER_COUNT; layer++) {
235
        for (row = 0; row < CUBE_COLUMN_COUNT; row++) {
236
            uint16_t var = row * GCS_REG_SIZE + (column / 2 * 9);
237
            switch (column % 2) {
238
                case 0:
239
                    cube_data_ptr->GCS[layer][var+0] = R & 0xFF;
240
                    cube_data_ptr->GCS[layer][var+1] = (G << 4) | (R >> 8);
241
                    cube_data_ptr->GCS[layer][var+2] = G >> 4;
242
                    cube_data_ptr->GCS[layer][var+3] = B & 0xFF;
243
                    cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0xF0) | (B >> 8);
244
                    break;
245
                case 1:
246
                    cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0x0F) | (R << 4);
247
                    cube_data_ptr->GCS[layer][var+5] = R >> 4;
248
                    cube_data_ptr->GCS[layer][var+6] = G & 0xFF;
249
                    cube_data_ptr->GCS[layer][var+7] = (B << 4) | (G >> 8);
250
                    cube_data_ptr->GCS[layer][var+8] = B >> 4;
251
                    break;
252
            }
253
        }
254
    }
255
}
256
 
231 Kevin 257
void Cube_Set_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t R, uint16_t G, uint16_t B) {
201 Kevin 258
    // Set the specified pixel to the given color
199 Kevin 259
    R &= 0x0FFF;
260
    G &= 0x0FFF;
261
    B &= 0x0FFF;
231 Kevin 262
    uint16_t var = row * GCS_REG_SIZE + (column / 2 * 9);
199 Kevin 263
    switch (column % 2) {
264
        case 0:
265
            cube_data_ptr->GCS[layer][var+0] = R & 0xFF;
266
            cube_data_ptr->GCS[layer][var+1] = (G << 4) | (R >> 8);
267
            cube_data_ptr->GCS[layer][var+2] = G >> 4;
268
            cube_data_ptr->GCS[layer][var+3] = B & 0xFF;
269
            cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0xF0) | (B >> 8);
270
            break;
271
        case 1:
272
            cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0x0F) | (R << 4);
273
            cube_data_ptr->GCS[layer][var+5] = R >> 4;
274
            cube_data_ptr->GCS[layer][var+6] = G & 0xFF;
275
            cube_data_ptr->GCS[layer][var+7] = (B << 4) | (G >> 8);
276
            cube_data_ptr->GCS[layer][var+8] = B >> 4;
277
            break;
278
    }
205 Kevin 279
}
280
 
231 Kevin 281
void Cube_Get_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t* R, uint16_t* G, uint16_t* B) {
282
    uint16_t var = row * GCS_REG_SIZE + (column / 2 * 9);
205 Kevin 283
    switch (column % 2) {
284
        // Concatenate lower byte and upper byte of each color channel
285
        case 0:
286
            *R = cube_data_ptr->GCS[layer][var+0] | ((cube_data_ptr->GCS[layer][var+1] & 0x0F) << 8);
287
            *G = (cube_data_ptr->GCS[layer][var+1] >> 4) | (cube_data_ptr->GCS[layer][var+2] << 4);
288
            *B = cube_data_ptr->GCS[layer][var+3] | ((cube_data_ptr->GCS[layer][var+4] & 0x0F) << 8);
289
            break;
290
        case 1:
291
            *R = (cube_data_ptr->GCS[layer][var+4] >> 4) | (cube_data_ptr->GCS[layer][var+5] << 4);
292
            *G = cube_data_ptr->GCS[layer][var+6] | ((cube_data_ptr->GCS[layer][var+7] & 0x0F) << 8);
293
            *B = (cube_data_ptr->GCS[layer][var+7] >> 4) | (cube_data_ptr->GCS[layer][var+8] << 4);
294
            break;
295
    }
296
}
297
 
231 Kevin 298
void Cube_Move_Pixel(uint8_t layer1, uint8_t row1, uint8_t column1, uint8_t layer2, uint8_t row2, uint8_t column2) {
206 Kevin 299
    // Copies data from pixel 1 to pixel 2
205 Kevin 300
    // Note: destination pixel value is overwritten
231 Kevin 301
    uint16_t prev_R, prev_G, prev_B;
205 Kevin 302
    Cube_Get_Pixel(layer1, row1, column1, &prev_R, &prev_G, &prev_B);
303
    Cube_Set_Pixel(layer2, row2, column2, prev_R, prev_G, prev_B);
304
}
305
 
264 Kevin 306
void Cube_Set_Sphere(uint8_t layer, uint8_t R, uint8_t G, uint8_t B) {
307
    // Super code inefficient (or is it?) lookup table
268 Kevin 308
    switch (layer % 9) {
264 Kevin 309
        case 0:
310
            Cube_Set_Pixel(3, 3, 3, R, G, B);
311
            Cube_Set_Pixel(3, 3, 4, R, G, B);
312
            Cube_Set_Pixel(3, 4, 3, R, G, B);
313
            Cube_Set_Pixel(3, 4, 4, R, G, B);
314
            Cube_Set_Pixel(4, 3, 3, R, G, B);
315
            Cube_Set_Pixel(4, 3, 4, R, G, B);
316
            Cube_Set_Pixel(4, 4, 3, R, G, B);
317
            Cube_Set_Pixel(4, 4, 4, R, G, B);
318
            break;
319
        case 1:
320
            Cube_Set_Pixel(2, 3, 3, R, G, B);
321
            Cube_Set_Pixel(2, 3, 4, R, G, B);
322
            Cube_Set_Pixel(2, 4, 3, R, G, B);
323
            Cube_Set_Pixel(2, 4, 4, R, G, B);
324
 
325
            Cube_Set_Pixel(5, 3, 3, R, G, B);
326
            Cube_Set_Pixel(5, 3, 4, R, G, B);
327
            Cube_Set_Pixel(5, 4, 3, R, G, B);
328
            Cube_Set_Pixel(5, 4, 4, R, G, B);
329
 
330
            Cube_Set_Pixel(3, 2, 3, R, G, B);
331
            Cube_Set_Pixel(3, 2, 4, R, G, B);
332
            Cube_Set_Pixel(3, 5, 3, R, G, B);
333
            Cube_Set_Pixel(3, 5, 4, R, G, B);
334
            Cube_Set_Pixel(3, 3, 2, R, G, B);
335
            Cube_Set_Pixel(3, 4, 2, R, G, B);
336
            Cube_Set_Pixel(3, 3, 5, R, G, B);
337
            Cube_Set_Pixel(3, 4, 5, R, G, B);
338
 
339
            Cube_Set_Pixel(4, 2, 3, R, G, B);
340
            Cube_Set_Pixel(4, 2, 4, R, G, B);
341
            Cube_Set_Pixel(4, 5, 3, R, G, B);
342
            Cube_Set_Pixel(4, 5, 4, R, G, B);
343
            Cube_Set_Pixel(4, 3, 2, R, G, B);
344
            Cube_Set_Pixel(4, 4, 2, R, G, B);
345
            Cube_Set_Pixel(4, 3, 5, R, G, B);
346
            Cube_Set_Pixel(4, 4, 5, R, G, B);
347
            break;
348
        case 2:
349
            Cube_Set_Pixel(1, 3, 3, R, G, B);
350
            Cube_Set_Pixel(1, 3, 4, R, G, B);
351
            Cube_Set_Pixel(1, 4, 3, R, G, B);
352
            Cube_Set_Pixel(1, 4, 4, R, G, B);
353
 
354
            Cube_Set_Pixel(6, 3, 3, R, G, B);
355
            Cube_Set_Pixel(6, 3, 4, R, G, B);
356
            Cube_Set_Pixel(6, 4, 3, R, G, B);
357
            Cube_Set_Pixel(6, 4, 4, R, G, B);
358
 
359
            Cube_Set_Pixel(3, 1, 3, R, G, B);
360
            Cube_Set_Pixel(3, 1, 4, R, G, B);
361
            Cube_Set_Pixel(3, 6, 3, R, G, B);
362
            Cube_Set_Pixel(3, 6, 4, R, G, B);
363
            Cube_Set_Pixel(3, 3, 1, R, G, B);
364
            Cube_Set_Pixel(3, 4, 1, R, G, B);
365
            Cube_Set_Pixel(3, 3, 6, R, G, B);
366
            Cube_Set_Pixel(3, 4, 6, R, G, B);
367
 
368
            Cube_Set_Pixel(3, 2, 2, R, G, B);
369
            Cube_Set_Pixel(3, 2, 5, R, G, B);
370
            Cube_Set_Pixel(3, 5, 5, R, G, B);
371
            Cube_Set_Pixel(3, 5, 2, R, G, B);
372
 
373
            Cube_Set_Pixel(4, 1, 3, R, G, B);
374
            Cube_Set_Pixel(4, 1, 4, R, G, B);
375
            Cube_Set_Pixel(4, 6, 3, R, G, B);
376
            Cube_Set_Pixel(4, 6, 4, R, G, B);
377
            Cube_Set_Pixel(4, 3, 1, R, G, B);
378
            Cube_Set_Pixel(4, 4, 1, R, G, B);
379
            Cube_Set_Pixel(4, 3, 6, R, G, B);
380
            Cube_Set_Pixel(4, 4, 6, R, G, B);
381
 
382
            Cube_Set_Pixel(4, 2, 2, R, G, B);
383
            Cube_Set_Pixel(4, 2, 5, R, G, B);
384
            Cube_Set_Pixel(4, 5, 5, R, G, B);
385
            Cube_Set_Pixel(4, 5, 2, R, G, B);
386
 
387
            Cube_Set_Pixel(2, 3, 2, R, G, B);
388
            Cube_Set_Pixel(2, 4, 2, R, G, B);
389
            Cube_Set_Pixel(2, 3, 5, R, G, B);
390
            Cube_Set_Pixel(2, 4, 5, R, G, B);
391
            Cube_Set_Pixel(2, 2, 3, R, G, B);
392
            Cube_Set_Pixel(2, 2, 4, R, G, B);
393
            Cube_Set_Pixel(2, 5, 3, R, G, B);
394
            Cube_Set_Pixel(2, 5, 4, R, G, B);
395
 
396
            Cube_Set_Pixel(2, 2, 2, R, G, B);
397
            Cube_Set_Pixel(2, 2, 5, R, G, B);
398
            Cube_Set_Pixel(2, 5, 2, R, G, B);
399
            Cube_Set_Pixel(2, 5, 5, R, G, B);
400
 
401
            Cube_Set_Pixel(5, 3, 2, R, G, B);
402
            Cube_Set_Pixel(5, 4, 2, R, G, B);
403
            Cube_Set_Pixel(5, 3, 5, R, G, B);
404
            Cube_Set_Pixel(5, 4, 5, R, G, B);
405
            Cube_Set_Pixel(5, 2, 3, R, G, B);
406
            Cube_Set_Pixel(5, 2, 4, R, G, B);
407
            Cube_Set_Pixel(5, 5, 3, R, G, B);
408
            Cube_Set_Pixel(5, 5, 4, R, G, B);
409
 
410
            Cube_Set_Pixel(5, 2, 2, R, G, B);
411
            Cube_Set_Pixel(5, 2, 5, R, G, B);
412
            Cube_Set_Pixel(5, 5, 2, R, G, B);
413
            Cube_Set_Pixel(5, 5, 5, R, G, B);
414
            break;
415
        case 3:
416
            Cube_Set_Pixel(0, 3, 3, R, G, B);
417
            Cube_Set_Pixel(0, 3, 4, R, G, B);
418
            Cube_Set_Pixel(0, 4, 3, R, G, B);
419
            Cube_Set_Pixel(0, 4, 4, R, G, B);
420
            Cube_Set_Pixel(7, 3, 3, R, G, B);
421
            Cube_Set_Pixel(7, 3, 4, R, G, B);
422
            Cube_Set_Pixel(7, 4, 3, R, G, B);
423
            Cube_Set_Pixel(7, 4, 4, R, G, B);
424
 
425
            Cube_Set_Pixel(3, 0, 3, R, G, B);
426
            Cube_Set_Pixel(3, 0, 4, R, G, B);
427
            Cube_Set_Pixel(3, 7, 3, R, G, B);
428
            Cube_Set_Pixel(3, 7, 4, R, G, B);
429
            Cube_Set_Pixel(3, 3, 0, R, G, B);
430
            Cube_Set_Pixel(3, 4, 0, R, G, B);
431
            Cube_Set_Pixel(3, 3, 7, R, G, B);
432
            Cube_Set_Pixel(3, 4, 7, R, G, B);
433
 
434
            Cube_Set_Pixel(3, 2, 6, R, G, B);
435
            Cube_Set_Pixel(3, 1, 5, R, G, B);
436
            Cube_Set_Pixel(3, 6, 2, R, G, B);
437
            Cube_Set_Pixel(3, 5, 1, R, G, B);
438
            Cube_Set_Pixel(3, 1, 2, R, G, B);
439
            Cube_Set_Pixel(3, 2, 1, R, G, B);
440
            Cube_Set_Pixel(3, 6, 5, R, G, B);
441
            Cube_Set_Pixel(3, 5, 6, R, G, B);
442
 
443
            Cube_Set_Pixel(4, 0, 3, R, G, B);
444
            Cube_Set_Pixel(4, 0, 4, R, G, B);
445
            Cube_Set_Pixel(4, 7, 3, R, G, B);
446
            Cube_Set_Pixel(4, 7, 4, R, G, B);
447
            Cube_Set_Pixel(4, 3, 0, R, G, B);
448
            Cube_Set_Pixel(4, 4, 0, R, G, B);
449
            Cube_Set_Pixel(4, 3, 7, R, G, B);
450
            Cube_Set_Pixel(4, 4, 7, R, G, B);
451
 
452
            Cube_Set_Pixel(4, 2, 6, R, G, B);
453
            Cube_Set_Pixel(4, 1, 5, R, G, B);
454
            Cube_Set_Pixel(4, 6, 2, R, G, B);
455
            Cube_Set_Pixel(4, 5, 1, R, G, B);
456
            Cube_Set_Pixel(4, 1, 2, R, G, B);
457
            Cube_Set_Pixel(4, 2, 1, R, G, B);
458
            Cube_Set_Pixel(4, 6, 5, R, G, B);
459
            Cube_Set_Pixel(4, 5, 6, R, G, B);
460
 
461
            Cube_Set_Pixel(1, 2, 5, R, G, B);
462
            Cube_Set_Pixel(1, 2, 4, R, G, B);
463
            Cube_Set_Pixel(1, 2, 3, R, G, B);
464
            Cube_Set_Pixel(1, 2, 2, R, G, B);
465
            Cube_Set_Pixel(1, 3, 5, R, G, B);
466
            Cube_Set_Pixel(1, 3, 2, R, G, B);
467
            Cube_Set_Pixel(1, 4, 5, R, G, B);
468
            Cube_Set_Pixel(1, 4, 2, R, G, B);
469
            Cube_Set_Pixel(1, 5, 5, R, G, B);
470
            Cube_Set_Pixel(1, 5, 4, R, G, B);
471
            Cube_Set_Pixel(1, 5, 3, R, G, B);
472
            Cube_Set_Pixel(1, 5, 2, R, G, B);
473
 
474
            Cube_Set_Pixel(2, 1, 5, R, G, B);
475
            Cube_Set_Pixel(2, 1, 4, R, G, B);
476
            Cube_Set_Pixel(2, 1, 3, R, G, B);
477
            Cube_Set_Pixel(2, 1, 2, R, G, B);
478
            Cube_Set_Pixel(2, 6, 5, R, G, B);
479
            Cube_Set_Pixel(2, 6, 4, R, G, B);
480
            Cube_Set_Pixel(2, 6, 3, R, G, B);
481
            Cube_Set_Pixel(2, 6, 2, R, G, B);
482
            Cube_Set_Pixel(2, 2, 6, R, G, B);
483
            Cube_Set_Pixel(2, 3, 6, R, G, B);
484
            Cube_Set_Pixel(2, 4, 6, R, G, B);
485
            Cube_Set_Pixel(2, 5, 6, R, G, B);
486
            Cube_Set_Pixel(2, 2, 1, R, G, B);
487
            Cube_Set_Pixel(2, 3, 1, R, G, B);
488
            Cube_Set_Pixel(2, 4, 1, R, G, B);
489
            Cube_Set_Pixel(2, 5, 1, R, G, B);
490
 
491
            Cube_Set_Pixel(5, 1, 5, R, G, B);
492
            Cube_Set_Pixel(5, 1, 4, R, G, B);
493
            Cube_Set_Pixel(5, 1, 3, R, G, B);
494
            Cube_Set_Pixel(5, 1, 2, R, G, B);
495
            Cube_Set_Pixel(5, 6, 5, R, G, B);
496
            Cube_Set_Pixel(5, 6, 4, R, G, B);
497
            Cube_Set_Pixel(5, 6, 3, R, G, B);
498
            Cube_Set_Pixel(5, 6, 2, R, G, B);
499
            Cube_Set_Pixel(5, 2, 6, R, G, B);
500
            Cube_Set_Pixel(5, 3, 6, R, G, B);
501
            Cube_Set_Pixel(5, 4, 6, R, G, B);
502
            Cube_Set_Pixel(5, 5, 6, R, G, B);
503
            Cube_Set_Pixel(5, 2, 1, R, G, B);
504
            Cube_Set_Pixel(5, 3, 1, R, G, B);
505
            Cube_Set_Pixel(5, 4, 1, R, G, B);
506
            Cube_Set_Pixel(5, 5, 1, R, G, B);
507
 
508
            Cube_Set_Pixel(6, 2, 5, R, G, B);
509
            Cube_Set_Pixel(6, 2, 4, R, G, B);
510
            Cube_Set_Pixel(6, 2, 3, R, G, B);
511
            Cube_Set_Pixel(6, 2, 2, R, G, B);
512
            Cube_Set_Pixel(6, 3, 5, R, G, B);
513
            Cube_Set_Pixel(6, 3, 2, R, G, B);
514
            Cube_Set_Pixel(6, 4, 5, R, G, B);
515
            Cube_Set_Pixel(6, 4, 2, R, G, B);
516
            Cube_Set_Pixel(6, 5, 5, R, G, B);
517
            Cube_Set_Pixel(6, 5, 4, R, G, B);
518
            Cube_Set_Pixel(6, 5, 3, R, G, B);
519
            Cube_Set_Pixel(6, 5, 2, R, G, B);
520
            break;
521
        case 4:
522
            Cube_Set_Pixel(0, 2, 5, R, G, B);
523
            Cube_Set_Pixel(0, 2, 4, R, G, B);
524
            Cube_Set_Pixel(0, 2, 3, R, G, B);
525
            Cube_Set_Pixel(0, 2, 2, R, G, B);
526
            Cube_Set_Pixel(0, 3, 5, R, G, B);
527
            Cube_Set_Pixel(0, 3, 2, R, G, B);
528
            Cube_Set_Pixel(0, 4, 5, R, G, B);
529
            Cube_Set_Pixel(0, 4, 2, R, G, B);
530
            Cube_Set_Pixel(0, 5, 5, R, G, B);
531
            Cube_Set_Pixel(0, 5, 4, R, G, B);
532
            Cube_Set_Pixel(0, 5, 3, R, G, B);
533
            Cube_Set_Pixel(0, 5, 2, R, G, B);
534
 
535
            Cube_Set_Pixel(7, 2, 5, R, G, B);
536
            Cube_Set_Pixel(7, 2, 4, R, G, B);
537
            Cube_Set_Pixel(7, 2, 3, R, G, B);
538
            Cube_Set_Pixel(7, 2, 2, R, G, B);
539
            Cube_Set_Pixel(7, 3, 5, R, G, B);
540
            Cube_Set_Pixel(7, 3, 2, R, G, B);
541
            Cube_Set_Pixel(7, 4, 5, R, G, B);
542
            Cube_Set_Pixel(7, 4, 2, R, G, B);
543
            Cube_Set_Pixel(7, 5, 5, R, G, B);
544
            Cube_Set_Pixel(7, 5, 4, R, G, B);
545
            Cube_Set_Pixel(7, 5, 3, R, G, B);
546
            Cube_Set_Pixel(7, 5, 2, R, G, B);
547
 
548
            Cube_Set_Pixel(1, 1, 5, R, G, B);
549
            Cube_Set_Pixel(1, 1, 4, R, G, B);
550
            Cube_Set_Pixel(1, 1, 3, R, G, B);
551
            Cube_Set_Pixel(1, 1, 2, R, G, B);
552
            Cube_Set_Pixel(1, 6, 5, R, G, B);
553
            Cube_Set_Pixel(1, 6, 4, R, G, B);
554
            Cube_Set_Pixel(1, 6, 3, R, G, B);
555
            Cube_Set_Pixel(1, 6, 2, R, G, B);
556
            Cube_Set_Pixel(1, 2, 6, R, G, B);
557
            Cube_Set_Pixel(1, 3, 6, R, G, B);
558
            Cube_Set_Pixel(1, 4, 6, R, G, B);
559
            Cube_Set_Pixel(1, 5, 6, R, G, B);
560
            Cube_Set_Pixel(1, 2, 1, R, G, B);
561
            Cube_Set_Pixel(1, 3, 1, R, G, B);
562
            Cube_Set_Pixel(1, 4, 1, R, G, B);
563
            Cube_Set_Pixel(1, 5, 1, R, G, B);
564
 
565
            Cube_Set_Pixel(6, 1, 5, R, G, B);
566
            Cube_Set_Pixel(6, 1, 4, R, G, B);
567
            Cube_Set_Pixel(6, 1, 3, R, G, B);
568
            Cube_Set_Pixel(6, 1, 2, R, G, B);
569
            Cube_Set_Pixel(6, 6, 5, R, G, B);
570
            Cube_Set_Pixel(6, 6, 4, R, G, B);
571
            Cube_Set_Pixel(6, 6, 3, R, G, B);
572
            Cube_Set_Pixel(6, 6, 2, R, G, B);
573
            Cube_Set_Pixel(6, 2, 6, R, G, B);
574
            Cube_Set_Pixel(6, 3, 6, R, G, B);
575
            Cube_Set_Pixel(6, 4, 6, R, G, B);
576
            Cube_Set_Pixel(6, 5, 6, R, G, B);
577
            Cube_Set_Pixel(6, 2, 1, R, G, B);
578
            Cube_Set_Pixel(6, 3, 1, R, G, B);
579
            Cube_Set_Pixel(6, 4, 1, R, G, B);
580
            Cube_Set_Pixel(6, 5, 1, R, G, B);
581
 
582
            Cube_Set_Pixel(2, 0, 5, R, G, B);
583
            Cube_Set_Pixel(2, 0, 4, R, G, B);
584
            Cube_Set_Pixel(2, 0, 3, R, G, B);
585
            Cube_Set_Pixel(2, 0, 2, R, G, B);
586
            Cube_Set_Pixel(2, 7, 5, R, G, B);
587
            Cube_Set_Pixel(2, 7, 4, R, G, B);
588
            Cube_Set_Pixel(2, 7, 3, R, G, B);
589
            Cube_Set_Pixel(2, 7, 2, R, G, B);
590
            Cube_Set_Pixel(2, 5, 0, R, G, B);
591
            Cube_Set_Pixel(2, 4, 0, R, G, B);
592
            Cube_Set_Pixel(2, 3, 0, R, G, B);
593
            Cube_Set_Pixel(2, 2, 0, R, G, B);
594
            Cube_Set_Pixel(2, 5, 7, R, G, B);
595
            Cube_Set_Pixel(2, 4, 7, R, G, B);
596
            Cube_Set_Pixel(2, 3, 7, R, G, B);
597
            Cube_Set_Pixel(2, 2, 7, R, G, B);
598
            Cube_Set_Pixel(2, 1, 1, R, G, B);
599
            Cube_Set_Pixel(2, 1, 6, R, G, B);
600
            Cube_Set_Pixel(2, 6, 1, R, G, B);
601
            Cube_Set_Pixel(2, 6, 6, R, G, B);
602
 
603
            Cube_Set_Pixel(5, 0, 5, R, G, B);
604
            Cube_Set_Pixel(5, 0, 4, R, G, B);
605
            Cube_Set_Pixel(5, 0, 3, R, G, B);
606
            Cube_Set_Pixel(5, 0, 2, R, G, B);
607
            Cube_Set_Pixel(5, 7, 5, R, G, B);
608
            Cube_Set_Pixel(5, 7, 4, R, G, B);
609
            Cube_Set_Pixel(5, 7, 3, R, G, B);
610
            Cube_Set_Pixel(5, 7, 2, R, G, B);
611
            Cube_Set_Pixel(5, 5, 0, R, G, B);
612
            Cube_Set_Pixel(5, 4, 0, R, G, B);
613
            Cube_Set_Pixel(5, 3, 0, R, G, B);
614
            Cube_Set_Pixel(5, 2, 0, R, G, B);
615
            Cube_Set_Pixel(5, 5, 7, R, G, B);
616
            Cube_Set_Pixel(5, 4, 7, R, G, B);
617
            Cube_Set_Pixel(5, 3, 7, R, G, B);
618
            Cube_Set_Pixel(5, 2, 7, R, G, B);
619
            Cube_Set_Pixel(5, 1, 1, R, G, B);
620
            Cube_Set_Pixel(5, 1, 6, R, G, B);
621
            Cube_Set_Pixel(5, 6, 1, R, G, B);
622
            Cube_Set_Pixel(5, 6, 6, R, G, B);
623
 
624
            Cube_Set_Pixel(3, 0, 2, R, G, B);
625
            Cube_Set_Pixel(3, 0, 5, R, G, B);
626
            Cube_Set_Pixel(3, 2, 0, R, G, B);
627
            Cube_Set_Pixel(3, 5, 0, R, G, B);
628
            Cube_Set_Pixel(3, 7, 2, R, G, B);
629
            Cube_Set_Pixel(3, 7, 5, R, G, B);
630
            Cube_Set_Pixel(3, 2, 7, R, G, B);
631
            Cube_Set_Pixel(3, 5, 7, R, G, B);
632
            Cube_Set_Pixel(3, 1, 1, R, G, B);
633
            Cube_Set_Pixel(3, 1, 6, R, G, B);
634
            Cube_Set_Pixel(3, 6, 1, R, G, B);
635
            Cube_Set_Pixel(3, 6, 6, R, G, B);
636
 
637
            Cube_Set_Pixel(4, 0, 2, R, G, B);
638
            Cube_Set_Pixel(4, 0, 5, R, G, B);
639
            Cube_Set_Pixel(4, 2, 0, R, G, B);
640
            Cube_Set_Pixel(4, 5, 0, R, G, B);
641
            Cube_Set_Pixel(4, 7, 2, R, G, B);
642
            Cube_Set_Pixel(4, 7, 5, R, G, B);
643
            Cube_Set_Pixel(4, 2, 7, R, G, B);
644
            Cube_Set_Pixel(4, 5, 7, R, G, B);
645
            Cube_Set_Pixel(4, 1, 1, R, G, B);
646
            Cube_Set_Pixel(4, 1, 6, R, G, B);
647
            Cube_Set_Pixel(4, 6, 1, R, G, B);
648
            Cube_Set_Pixel(4, 6, 6, R, G, B);
649
            break;
650
        case 5:
651
            Cube_Set_Pixel(0, 1, 5, R, G, B);
652
            Cube_Set_Pixel(0, 1, 4, R, G, B);
653
            Cube_Set_Pixel(0, 1, 3, R, G, B);
654
            Cube_Set_Pixel(0, 1, 2, R, G, B);
655
            Cube_Set_Pixel(0, 6, 5, R, G, B);
656
            Cube_Set_Pixel(0, 6, 4, R, G, B);
657
            Cube_Set_Pixel(0, 6, 3, R, G, B);
658
            Cube_Set_Pixel(0, 6, 2, R, G, B);
659
            Cube_Set_Pixel(0, 2, 6, R, G, B);
660
            Cube_Set_Pixel(0, 3, 6, R, G, B);
661
            Cube_Set_Pixel(0, 4, 6, R, G, B);
662
            Cube_Set_Pixel(0, 5, 6, R, G, B);
663
            Cube_Set_Pixel(0, 2, 1, R, G, B);
664
            Cube_Set_Pixel(0, 3, 1, R, G, B);
665
            Cube_Set_Pixel(0, 4, 1, R, G, B);
666
            Cube_Set_Pixel(0, 5, 1, R, G, B);
667
 
668
            Cube_Set_Pixel(1, 0, 2, R, G, B);
669
            Cube_Set_Pixel(1, 0, 3, R, G, B);
670
            Cube_Set_Pixel(1, 0, 4, R, G, B);
671
            Cube_Set_Pixel(1, 0, 5, R, G, B);
672
            Cube_Set_Pixel(1, 1, 6, R, G, B);
673
            Cube_Set_Pixel(1, 2, 7, R, G, B);
674
            Cube_Set_Pixel(1, 3, 7, R, G, B);
675
            Cube_Set_Pixel(1, 4, 7, R, G, B);
676
            Cube_Set_Pixel(1, 5, 7, R, G, B);
677
            Cube_Set_Pixel(1, 6, 6, R, G, B);
678
            Cube_Set_Pixel(1, 7, 5, R, G, B);
679
            Cube_Set_Pixel(1, 7, 4, R, G, B);
680
            Cube_Set_Pixel(1, 7, 3, R, G, B);
681
            Cube_Set_Pixel(1, 7, 2, R, G, B);
682
            Cube_Set_Pixel(1, 6, 1, R, G, B);
683
            Cube_Set_Pixel(1, 5, 0, R, G, B);
684
            Cube_Set_Pixel(1, 4, 0, R, G, B);
685
            Cube_Set_Pixel(1, 3, 0, R, G, B);
686
            Cube_Set_Pixel(1, 2, 0, R, G, B);
687
            Cube_Set_Pixel(1, 1, 1, R, G, B);
688
 
689
            Cube_Set_Pixel(2, 0, 1, R, G, B);
690
            Cube_Set_Pixel(2, 1, 0, R, G, B);
691
            Cube_Set_Pixel(2, 0, 6, R, G, B);
692
            Cube_Set_Pixel(2, 1, 7, R, G, B);
693
            Cube_Set_Pixel(2, 6, 7, R, G, B);
694
            Cube_Set_Pixel(2, 7, 6, R, G, B);
695
            Cube_Set_Pixel(2, 6, 0, R, G, B);
696
            Cube_Set_Pixel(2, 7, 1, R, G, B);
697
 
698
            Cube_Set_Pixel(3, 0, 1, R, G, B);
699
            Cube_Set_Pixel(3, 1, 0, R, G, B);
700
            Cube_Set_Pixel(3, 0, 6, R, G, B);
701
            Cube_Set_Pixel(3, 1, 7, R, G, B);
702
            Cube_Set_Pixel(3, 6, 7, R, G, B);
703
            Cube_Set_Pixel(3, 7, 6, R, G, B);
704
            Cube_Set_Pixel(3, 6, 0, R, G, B);
705
            Cube_Set_Pixel(3, 7, 1, R, G, B);
706
 
707
            Cube_Set_Pixel(4, 0, 1, R, G, B);
708
            Cube_Set_Pixel(4, 1, 0, R, G, B);
709
            Cube_Set_Pixel(4, 0, 6, R, G, B);
710
            Cube_Set_Pixel(4, 1, 7, R, G, B);
711
            Cube_Set_Pixel(4, 6, 7, R, G, B);
712
            Cube_Set_Pixel(4, 7, 6, R, G, B);
713
            Cube_Set_Pixel(4, 6, 0, R, G, B);
714
            Cube_Set_Pixel(4, 7, 1, R, G, B);
715
 
716
            Cube_Set_Pixel(5, 0, 1, R, G, B);
717
            Cube_Set_Pixel(5, 1, 0, R, G, B);
718
            Cube_Set_Pixel(5, 0, 6, R, G, B);
719
            Cube_Set_Pixel(5, 1, 7, R, G, B);
720
            Cube_Set_Pixel(5, 6, 7, R, G, B);
721
            Cube_Set_Pixel(5, 7, 6, R, G, B);
722
            Cube_Set_Pixel(5, 6, 0, R, G, B);
723
            Cube_Set_Pixel(5, 7, 1, R, G, B);
724
 
725
 
726
            Cube_Set_Pixel(6, 0, 2, R, G, B);
727
            Cube_Set_Pixel(6, 0, 3, R, G, B);
728
            Cube_Set_Pixel(6, 0, 4, R, G, B);
729
            Cube_Set_Pixel(6, 0, 5, R, G, B);
730
            Cube_Set_Pixel(6, 1, 6, R, G, B);
731
            Cube_Set_Pixel(6, 2, 7, R, G, B);
732
            Cube_Set_Pixel(6, 3, 7, R, G, B);
733
            Cube_Set_Pixel(6, 4, 7, R, G, B);
734
            Cube_Set_Pixel(6, 5, 7, R, G, B);
735
            Cube_Set_Pixel(6, 6, 6, R, G, B);
736
            Cube_Set_Pixel(6, 7, 5, R, G, B);
737
            Cube_Set_Pixel(6, 7, 4, R, G, B);
738
            Cube_Set_Pixel(6, 7, 3, R, G, B);
739
            Cube_Set_Pixel(6, 7, 2, R, G, B);
740
            Cube_Set_Pixel(6, 6, 1, R, G, B);
741
            Cube_Set_Pixel(6, 5, 0, R, G, B);
742
            Cube_Set_Pixel(6, 4, 0, R, G, B);
743
            Cube_Set_Pixel(6, 3, 0, R, G, B);
744
            Cube_Set_Pixel(6, 2, 0, R, G, B);
745
            Cube_Set_Pixel(6, 1, 1, R, G, B);
746
 
747
            Cube_Set_Pixel(7, 1, 5, R, G, B);
748
            Cube_Set_Pixel(7, 1, 4, R, G, B);
749
            Cube_Set_Pixel(7, 1, 3, R, G, B);
750
            Cube_Set_Pixel(7, 1, 2, R, G, B);
751
            Cube_Set_Pixel(7, 6, 5, R, G, B);
752
            Cube_Set_Pixel(7, 6, 4, R, G, B);
753
            Cube_Set_Pixel(7, 6, 3, R, G, B);
754
            Cube_Set_Pixel(7, 6, 2, R, G, B);
755
            Cube_Set_Pixel(7, 2, 6, R, G, B);
756
            Cube_Set_Pixel(7, 3, 6, R, G, B);
757
            Cube_Set_Pixel(7, 4, 6, R, G, B);
758
            Cube_Set_Pixel(7, 5, 6, R, G, B);
759
            Cube_Set_Pixel(7, 2, 1, R, G, B);
760
            Cube_Set_Pixel(7, 3, 1, R, G, B);
761
            Cube_Set_Pixel(7, 4, 1, R, G, B);
762
            Cube_Set_Pixel(7, 5, 1, R, G, B);
763
            break;
764
        case 6:
765
            Cube_Set_Pixel(0, 0, 2, R, G, B);
766
            Cube_Set_Pixel(0, 0, 3, R, G, B);
767
            Cube_Set_Pixel(0, 0, 4, R, G, B);
768
            Cube_Set_Pixel(0, 0, 5, R, G, B);
769
            Cube_Set_Pixel(0, 1, 1, R, G, B);
770
            Cube_Set_Pixel(0, 1, 6, R, G, B);
771
            Cube_Set_Pixel(0, 2, 0, R, G, B);
772
            Cube_Set_Pixel(0, 2, 7, R, G, B);
773
            Cube_Set_Pixel(0, 3, 0, R, G, B);
774
            Cube_Set_Pixel(0, 3, 7, R, G, B);
775
            Cube_Set_Pixel(0, 4, 0, R, G, B);
776
            Cube_Set_Pixel(0, 4, 7, R, G, B);
777
            Cube_Set_Pixel(0, 5, 0, R, G, B);
778
            Cube_Set_Pixel(0, 5, 7, R, G, B);
779
            Cube_Set_Pixel(0, 6, 6, R, G, B);
780
            Cube_Set_Pixel(0, 6, 1, R, G, B);
781
            Cube_Set_Pixel(0, 7, 2, R, G, B);
782
            Cube_Set_Pixel(0, 7, 3, R, G, B);
783
            Cube_Set_Pixel(0, 7, 4, R, G, B);
784
            Cube_Set_Pixel(0, 7, 5, R, G, B);
785
 
786
            Cube_Set_Pixel(1, 0, 1, R, G, B);
787
            Cube_Set_Pixel(1, 1, 0, R, G, B);
788
            Cube_Set_Pixel(1, 0, 6, R, G, B);
789
            Cube_Set_Pixel(1, 1, 7, R, G, B);
790
            Cube_Set_Pixel(1, 6, 7, R, G, B);
791
            Cube_Set_Pixel(1, 7, 6, R, G, B);
792
            Cube_Set_Pixel(1, 6, 0, R, G, B);
793
            Cube_Set_Pixel(1, 7, 1, R, G, B);
794
 
795
            Cube_Set_Pixel(2, 0, 0, R, G, B);
796
            Cube_Set_Pixel(2, 0, 7, R, G, B);
797
            Cube_Set_Pixel(2, 7, 7, R, G, B);
798
            Cube_Set_Pixel(2, 7, 0, R, G, B);
799
 
800
            Cube_Set_Pixel(3, 0, 0, R, G, B);
801
            Cube_Set_Pixel(3, 0, 7, R, G, B);
802
            Cube_Set_Pixel(3, 7, 7, R, G, B);
803
            Cube_Set_Pixel(3, 7, 0, R, G, B);
804
 
805
            Cube_Set_Pixel(4, 0, 0, R, G, B);
806
            Cube_Set_Pixel(4, 0, 7, R, G, B);
807
            Cube_Set_Pixel(4, 7, 7, R, G, B);
808
            Cube_Set_Pixel(4, 7, 0, R, G, B);
809
 
810
            Cube_Set_Pixel(5, 0, 0, R, G, B);
811
            Cube_Set_Pixel(5, 0, 7, R, G, B);
812
            Cube_Set_Pixel(5, 7, 7, R, G, B);
813
            Cube_Set_Pixel(5, 7, 0, R, G, B);
814
 
815
            Cube_Set_Pixel(6, 0, 1, R, G, B);
816
            Cube_Set_Pixel(6, 1, 0, R, G, B);
817
            Cube_Set_Pixel(6, 0, 6, R, G, B);
818
            Cube_Set_Pixel(6, 1, 7, R, G, B);
819
            Cube_Set_Pixel(6, 6, 7, R, G, B);
820
            Cube_Set_Pixel(6, 7, 6, R, G, B);
821
            Cube_Set_Pixel(6, 6, 0, R, G, B);
822
            Cube_Set_Pixel(6, 7, 1, R, G, B);
823
 
824
            Cube_Set_Pixel(7, 0, 2, R, G, B);
825
            Cube_Set_Pixel(7, 0, 3, R, G, B);
826
            Cube_Set_Pixel(7, 0, 4, R, G, B);
827
            Cube_Set_Pixel(7, 0, 5, R, G, B);
828
            Cube_Set_Pixel(7, 1, 1, R, G, B);
829
            Cube_Set_Pixel(7, 1, 6, R, G, B);
830
            Cube_Set_Pixel(7, 2, 0, R, G, B);
831
            Cube_Set_Pixel(7, 2, 7, R, G, B);
832
            Cube_Set_Pixel(7, 3, 0, R, G, B);
833
            Cube_Set_Pixel(7, 3, 7, R, G, B);
834
            Cube_Set_Pixel(7, 4, 0, R, G, B);
835
            Cube_Set_Pixel(7, 4, 7, R, G, B);
836
            Cube_Set_Pixel(7, 5, 0, R, G, B);
837
            Cube_Set_Pixel(7, 5, 7, R, G, B);
838
            Cube_Set_Pixel(7, 6, 6, R, G, B);
839
            Cube_Set_Pixel(7, 6, 1, R, G, B);
840
            Cube_Set_Pixel(7, 7, 2, R, G, B);
841
            Cube_Set_Pixel(7, 7, 3, R, G, B);
842
            Cube_Set_Pixel(7, 7, 4, R, G, B);
843
            Cube_Set_Pixel(7, 7, 5, R, G, B);
844
            break;
845
        case 7:
846
            Cube_Set_Pixel(0, 0, 1, R, G, B);
847
            Cube_Set_Pixel(0, 1, 0, R, G, B);
848
            Cube_Set_Pixel(0, 0, 6, R, G, B);
849
            Cube_Set_Pixel(0, 1, 7, R, G, B);
850
            Cube_Set_Pixel(0, 6, 7, R, G, B);
851
            Cube_Set_Pixel(0, 7, 6, R, G, B);
852
            Cube_Set_Pixel(0, 7, 1, R, G, B);
853
            Cube_Set_Pixel(0, 6, 0, R, G, B);
854
 
855
            Cube_Set_Pixel(1, 0, 0, R, G, B);
856
            Cube_Set_Pixel(1, 0, 7, R, G, B);
857
            Cube_Set_Pixel(1, 7, 7, R, G, B);
858
            Cube_Set_Pixel(1, 7, 0, R, G, B);
859
 
860
            Cube_Set_Pixel(6, 0, 0, R, G, B);
861
            Cube_Set_Pixel(6, 0, 7, R, G, B);
862
            Cube_Set_Pixel(6, 7, 7, R, G, B);
863
            Cube_Set_Pixel(6, 7, 0, R, G, B);
864
 
865
            Cube_Set_Pixel(7, 0, 1, R, G, B);
866
            Cube_Set_Pixel(7, 1, 0, R, G, B);
867
            Cube_Set_Pixel(7, 0, 6, R, G, B);
868
            Cube_Set_Pixel(7, 1, 7, R, G, B);
869
            Cube_Set_Pixel(7, 6, 7, R, G, B);
870
            Cube_Set_Pixel(7, 7, 6, R, G, B);
871
            Cube_Set_Pixel(7, 7, 1, R, G, B);
872
            Cube_Set_Pixel(7, 6, 0, R, G, B);
873
            break;
874
        case 8:
875
            Cube_Set_Pixel(0, 0, 0, R, G, B);
876
            Cube_Set_Pixel(0, 0, 7, R, G, B);
877
            Cube_Set_Pixel(0, 7, 7, R, G, B);
878
            Cube_Set_Pixel(0, 7, 0, R, G, B);
879
 
880
            Cube_Set_Pixel(7, 0, 0, R, G, B);
881
            Cube_Set_Pixel(7, 0, 7, R, G, B);
882
            Cube_Set_Pixel(7, 7, 7, R, G, B);
883
            Cube_Set_Pixel(7, 7, 0, R, G, B);
884
            break;
885
        default:
886
            break;
887
    }
888
}
889
 
890
void Cube_Set_Shell(uint8_t layer, uint8_t R, uint8_t G, uint8_t B) {
891
    // Sets the specified shell to the specific color
892
    // Shell 0 is the outermost layer, 3 is the innermost cube of pixels
893
    uint8_t i, j, k;
894
 
895
    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
896
        if ((layer == 0 || layer == 4)&&(i == 0 || i == 7)) {
897
            Cube_Set_Layer(i,R,G,B);
898
        } else if ((layer == 1 || layer == 4)&&(i == 1 || i == 6)) {
899
            for (j = 1; j < CUBE_ROW_COUNT-1; j++)
900
                for (k = 1; k < CUBE_COLUMN_COUNT-1; k++)
901
                    Cube_Set_Pixel(i,j,k,R,G,B);
902
        } else if ((layer == 2 || layer == 4)&&(i == 2 || i == 5)) {
903
            for (j = 2; j < CUBE_ROW_COUNT-2; j++)
904
                for (k = 2; k < CUBE_COLUMN_COUNT-2; k++)
905
                    Cube_Set_Pixel(i,j,k,R,G,B);
906
        } else if ((layer == 3 || layer == 4)&&(i == 3 || i == 4)) {
907
            for (j = 3; j < CUBE_ROW_COUNT-3; j++)
908
                for (k = 3; k < CUBE_COLUMN_COUNT-3; k++)
909
                    Cube_Set_Pixel(i,j,k,R,G,B);
910
        }
911
 
912
        if ((layer == 0 || layer == 4)&&(i > 0 && i < 8)) {
913
            for (j = 0; j < 8; j++) {
914
                Cube_Set_Pixel(i,j,0,R,G,B);
915
                Cube_Set_Pixel(i,j,7,R,G,B);
916
                Cube_Set_Pixel(i,0,j,R,G,B);
917
                Cube_Set_Pixel(i,7,j,R,G,B);
918
            }
919
        }
920
        if ((layer == 1 || layer == 4)&&(i > 1 && i < 7)) {
921
            for (j = 1; j < 7; j++) {
922
                Cube_Set_Pixel(i,j,1,R,G,B);
923
                Cube_Set_Pixel(i,j,6,R,G,B);
924
                Cube_Set_Pixel(i,1,j,R,G,B);
925
                Cube_Set_Pixel(i,6,j,R,G,B);
926
            }
927
        }
928
        if ((layer == 2 || layer == 4)&&(i > 2 && i < 6)) {
929
            for (j = 2; j < 6; j++) {
930
                Cube_Set_Pixel(i,j,2,R,G,B);
931
                Cube_Set_Pixel(i,j,5,R,G,B);
932
                Cube_Set_Pixel(i,2,j,R,G,B);
933
                Cube_Set_Pixel(i,5,j,R,G,B);
934
            }
935
        }
936
    }
937
}
938
 
231 Kevin 939
void Cube_Rotate_Shell(uint8_t shell, uint8_t direction) {
205 Kevin 940
    // Shell is the layer to rotate, with the outermost being 0
231 Kevin 941
    uint8_t layer;
942
    uint16_t origin_R, origin_G, origin_B;
205 Kevin 943
    for (layer = 0; layer < CUBE_LAYER_COUNT; layer++) {
206 Kevin 944
        if (direction) {
945
            switch(shell) {
946
                case 0:
947
                    // Rotate outermost layer
948
                    Cube_Get_Pixel(layer, 0, 0, &origin_R, &origin_G, &origin_B);
949
                    Cube_Move_Pixel(layer, 0, 1, layer, 0, 0);
950
                    Cube_Move_Pixel(layer, 0, 2, layer, 0, 1);
951
                    Cube_Move_Pixel(layer, 0, 3, layer, 0, 2);
952
                    Cube_Move_Pixel(layer, 0, 4, layer, 0, 3);
953
                    Cube_Move_Pixel(layer, 0, 5, layer, 0, 4);
954
                    Cube_Move_Pixel(layer, 0, 6, layer, 0, 5);
955
                    Cube_Move_Pixel(layer, 0, 7, layer, 0, 6);
956
                    Cube_Move_Pixel(layer, 1, 7, layer, 0, 7);
957
                    Cube_Move_Pixel(layer, 2, 7, layer, 1, 7);
958
                    Cube_Move_Pixel(layer, 3, 7, layer, 2, 7);
959
                    Cube_Move_Pixel(layer, 4, 7, layer, 3, 7);
960
                    Cube_Move_Pixel(layer, 5, 7, layer, 4, 7);
961
                    Cube_Move_Pixel(layer, 6, 7, layer, 5, 7);
962
                    Cube_Move_Pixel(layer, 7, 7, layer, 6, 7);
963
                    Cube_Move_Pixel(layer, 7, 6, layer, 7, 7);
964
                    Cube_Move_Pixel(layer, 7, 5, layer, 7, 6);
965
                    Cube_Move_Pixel(layer, 7, 4, layer, 7, 5);
966
                    Cube_Move_Pixel(layer, 7, 3, layer, 7, 4);
967
                    Cube_Move_Pixel(layer, 7, 2, layer, 7, 3);
968
                    Cube_Move_Pixel(layer, 7, 1, layer, 7, 2);
969
                    Cube_Move_Pixel(layer, 7, 0, layer, 7, 1);
970
                    Cube_Move_Pixel(layer, 6, 0, layer, 7, 0);
971
                    Cube_Move_Pixel(layer, 5, 0, layer, 6, 0);
972
                    Cube_Move_Pixel(layer, 4, 0, layer, 5, 0);
973
                    Cube_Move_Pixel(layer, 3, 0, layer, 4, 0);
974
                    Cube_Move_Pixel(layer, 2, 0, layer, 3, 0);
975
                    Cube_Move_Pixel(layer, 1, 0, layer, 2, 0);
976
                    Cube_Set_Pixel(layer, 1, 0, origin_R, origin_G, origin_B);
977
                    break;
978
                case 1:
979
                    // Rotate second to outermost layer
980
                    Cube_Get_Pixel(layer, 1, 1, &origin_R, &origin_G, &origin_B);
981
                    Cube_Move_Pixel(layer, 1, 2, layer, 1, 1);
982
                    Cube_Move_Pixel(layer, 1, 3, layer, 1, 2);
983
                    Cube_Move_Pixel(layer, 1, 4, layer, 1, 3);
984
                    Cube_Move_Pixel(layer, 1, 5, layer, 1, 4);
985
                    Cube_Move_Pixel(layer, 1, 6, layer, 1, 5);
986
                    Cube_Move_Pixel(layer, 2, 6, layer, 1, 6);
987
                    Cube_Move_Pixel(layer, 3, 6, layer, 2, 6);
988
                    Cube_Move_Pixel(layer, 4, 6, layer, 3, 6);
989
                    Cube_Move_Pixel(layer, 5, 6, layer, 4, 6);
990
                    Cube_Move_Pixel(layer, 6, 6, layer, 5, 6);
991
                    Cube_Move_Pixel(layer, 6, 5, layer, 6, 6);
992
                    Cube_Move_Pixel(layer, 6, 4, layer, 6, 5);
993
                    Cube_Move_Pixel(layer, 6, 3, layer, 6, 4);
994
                    Cube_Move_Pixel(layer, 6, 2, layer, 6, 3);
995
                    Cube_Move_Pixel(layer, 6, 1, layer, 6, 2);
996
                    Cube_Move_Pixel(layer, 5, 1, layer, 6, 1);
997
                    Cube_Move_Pixel(layer, 4, 1, layer, 5, 1);
998
                    Cube_Move_Pixel(layer, 3, 1, layer, 4, 1);
999
                    Cube_Move_Pixel(layer, 2, 1, layer, 3, 1);
1000
                    Cube_Set_Pixel(layer, 2, 1, origin_R, origin_G, origin_B);
1001
                    break;
1002
                case 2:
1003
                    // Rotate second to innermost layer
1004
                    Cube_Get_Pixel(layer, 2, 2, &origin_R, &origin_G, &origin_B);
1005
                    Cube_Move_Pixel(layer, 2, 3, layer, 2, 2);
1006
                    Cube_Move_Pixel(layer, 2, 4, layer, 2, 3);
1007
                    Cube_Move_Pixel(layer, 2, 5, layer, 2, 4);
1008
                    Cube_Move_Pixel(layer, 3, 5, layer, 2, 5);
1009
                    Cube_Move_Pixel(layer, 4, 5, layer, 3, 5);
1010
                    Cube_Move_Pixel(layer, 5, 5, layer, 4, 5);
1011
                    Cube_Move_Pixel(layer, 5, 4, layer, 5, 5);
1012
                    Cube_Move_Pixel(layer, 5, 3, layer, 5, 4);
1013
                    Cube_Move_Pixel(layer, 5, 2, layer, 5, 3);
1014
                    Cube_Move_Pixel(layer, 4, 2, layer, 5, 2);
1015
                    Cube_Move_Pixel(layer, 3, 2, layer, 4, 2);
1016
                    Cube_Set_Pixel(layer, 3, 2, origin_R, origin_G, origin_B);
1017
                    break;
1018
                case 3:
1019
                    // Rotate innermost layer
1020
                    Cube_Get_Pixel(layer, 3, 3, &origin_R, &origin_G, &origin_B);
1021
                    Cube_Move_Pixel(layer, 3, 4, layer, 3, 3);
1022
                    Cube_Move_Pixel(layer, 4, 4, layer, 3, 4);
1023
                    Cube_Move_Pixel(layer, 4, 3, layer, 4, 4);
1024
                    Cube_Set_Pixel(layer, 4, 3, origin_R, origin_G, origin_B);
1025
                    break;
1026
            }
1027
        } else {
1028
            switch(shell) {
1029
                case 0:
1030
                    // Rotate outermost layer
1031
                    Cube_Get_Pixel(layer, 0, 0, &origin_R, &origin_G, &origin_B);
1032
                    Cube_Move_Pixel(layer, 1, 0, layer, 0, 0);
1033
                    Cube_Move_Pixel(layer, 2, 0, layer, 1, 0);
1034
                    Cube_Move_Pixel(layer, 3, 0, layer, 2, 0);
1035
                    Cube_Move_Pixel(layer, 4, 0, layer, 3, 0);
1036
                    Cube_Move_Pixel(layer, 5, 0, layer, 4, 0);
1037
                    Cube_Move_Pixel(layer, 6, 0, layer, 5, 0);
1038
                    Cube_Move_Pixel(layer, 7, 0, layer, 6, 0);
1039
                    Cube_Move_Pixel(layer, 7, 1, layer, 7, 0);
1040
                    Cube_Move_Pixel(layer, 7, 2, layer, 7, 1);
1041
                    Cube_Move_Pixel(layer, 7, 3, layer, 7, 2);
1042
                    Cube_Move_Pixel(layer, 7, 4, layer, 7, 3);
1043
                    Cube_Move_Pixel(layer, 7, 5, layer, 7, 4);
1044
                    Cube_Move_Pixel(layer, 7, 6, layer, 7, 5);
1045
                    Cube_Move_Pixel(layer, 7, 7, layer, 7, 6);
1046
                    Cube_Move_Pixel(layer, 6, 7, layer, 7, 7);
1047
                    Cube_Move_Pixel(layer, 5, 7, layer, 6, 7);
1048
                    Cube_Move_Pixel(layer, 4, 7, layer, 5, 7);
1049
                    Cube_Move_Pixel(layer, 3, 7, layer, 4, 7);
1050
                    Cube_Move_Pixel(layer, 2, 7, layer, 3, 7);
1051
                    Cube_Move_Pixel(layer, 1, 7, layer, 2, 7);
1052
                    Cube_Move_Pixel(layer, 0, 7, layer, 1, 7);
1053
                    Cube_Move_Pixel(layer, 0, 6, layer, 0, 7);
1054
                    Cube_Move_Pixel(layer, 0, 5, layer, 0, 6);
1055
                    Cube_Move_Pixel(layer, 0, 4, layer, 0, 5);
1056
                    Cube_Move_Pixel(layer, 0, 3, layer, 0, 4);
1057
                    Cube_Move_Pixel(layer, 0, 2, layer, 0, 3);
1058
                    Cube_Move_Pixel(layer, 0, 1, layer, 0, 2);
1059
                    Cube_Set_Pixel(layer, 0, 1, origin_R, origin_G, origin_B);
1060
                    break;
1061
                case 1:
1062
                    // Rotate second to outermost layer
1063
                    Cube_Get_Pixel(layer, 1, 1, &origin_R, &origin_G, &origin_B);
1064
                    Cube_Move_Pixel(layer, 2, 1, layer, 1, 1);
1065
                    Cube_Move_Pixel(layer, 3, 1, layer, 2, 1);
1066
                    Cube_Move_Pixel(layer, 4, 1, layer, 3, 1);
1067
                    Cube_Move_Pixel(layer, 5, 1, layer, 4, 1);
1068
                    Cube_Move_Pixel(layer, 6, 1, layer, 5, 1);
1069
                    Cube_Move_Pixel(layer, 6, 2, layer, 6, 1);
1070
                    Cube_Move_Pixel(layer, 6, 3, layer, 6, 2);
1071
                    Cube_Move_Pixel(layer, 6, 4, layer, 6, 3);
1072
                    Cube_Move_Pixel(layer, 6, 5, layer, 6, 4);
1073
                    Cube_Move_Pixel(layer, 6, 6, layer, 6, 5);
1074
                    Cube_Move_Pixel(layer, 5, 6, layer, 6, 6);
1075
                    Cube_Move_Pixel(layer, 4, 6, layer, 5, 6);
1076
                    Cube_Move_Pixel(layer, 3, 6, layer, 4, 6);
1077
                    Cube_Move_Pixel(layer, 2, 6, layer, 3, 6);
1078
                    Cube_Move_Pixel(layer, 1, 6, layer, 2, 6);
1079
                    Cube_Move_Pixel(layer, 1, 5, layer, 1, 6);
1080
                    Cube_Move_Pixel(layer, 1, 4, layer, 1, 5);
1081
                    Cube_Move_Pixel(layer, 1, 3, layer, 1, 4);
1082
                    Cube_Move_Pixel(layer, 1, 2, layer, 1, 3);
1083
                    Cube_Set_Pixel(layer, 1, 2, origin_R, origin_G, origin_B);
1084
                    break;
1085
                case 2:
1086
                    // Rotate second to innermost layer
1087
                    Cube_Get_Pixel(layer, 2, 2, &origin_R, &origin_G, &origin_B);
1088
                    Cube_Move_Pixel(layer, 3, 2, layer, 2, 2);
1089
                    Cube_Move_Pixel(layer, 4, 2, layer, 3, 2);
1090
                    Cube_Move_Pixel(layer, 5, 2, layer, 4, 2);
1091
                    Cube_Move_Pixel(layer, 5, 3, layer, 5, 2);
1092
                    Cube_Move_Pixel(layer, 5, 4, layer, 5, 3);
1093
                    Cube_Move_Pixel(layer, 5, 5, layer, 5, 4);
1094
                    Cube_Move_Pixel(layer, 4, 5, layer, 5, 5);
1095
                    Cube_Move_Pixel(layer, 3, 5, layer, 4, 5);
1096
                    Cube_Move_Pixel(layer, 2, 5, layer, 3, 5);
1097
                    Cube_Move_Pixel(layer, 2, 4, layer, 2, 5);
1098
                    Cube_Move_Pixel(layer, 2, 3, layer, 2, 4);
1099
                    Cube_Set_Pixel(layer, 2, 3, origin_R, origin_G, origin_B);
1100
                    break;
1101
                case 3:
1102
                    // Rotate innermost layer
1103
                    Cube_Get_Pixel(layer, 3, 3, &origin_R, &origin_G, &origin_B);
1104
                    Cube_Move_Pixel(layer, 4, 3, layer, 3, 3);
1105
                    Cube_Move_Pixel(layer, 4, 4, layer, 4, 3);
1106
                    Cube_Move_Pixel(layer, 3, 4, layer, 4, 4);
1107
                    Cube_Set_Pixel(layer, 3, 4, origin_R, origin_G, origin_B);
1108
                    break;
1109
            }
205 Kevin 1110
        }
1111
    }
1112
}
1113
 
231 Kevin 1114
void Cube_Rotate(uint8_t direction) {
205 Kevin 1115
    // Rotate outermost layer
206 Kevin 1116
    Cube_Rotate_Shell(0, direction);
205 Kevin 1117
    // Rotate second to outermost layer
1118
    if ((cube_data_ptr->rotation_counter != 1) && (cube_data_ptr->rotation_counter != 5)) {
206 Kevin 1119
        Cube_Rotate_Shell(1, direction);
205 Kevin 1120
    }
1121
    // Rotate second to innermost layer
1122
    if ((cube_data_ptr->rotation_counter != 0) && (cube_data_ptr->rotation_counter != 2) &&
1123
        (cube_data_ptr->rotation_counter != 4) && (cube_data_ptr->rotation_counter != 6)) {
206 Kevin 1124
        Cube_Rotate_Shell(2, direction);
205 Kevin 1125
    }
1126
    // Rotate innermost layer
1127
    if ((cube_data_ptr->rotation_counter == 3) || (cube_data_ptr->rotation_counter == 7)) {
206 Kevin 1128
        Cube_Rotate_Shell(3, direction);
205 Kevin 1129
    }
1130
 
209 Kevin 1131
    if (direction == 0) {
1132
        cube_data_ptr->rotation_counter = (cube_data_ptr->rotation_counter == CUBE_ROTATIONS - 1)
1133
                ? 0 : cube_data_ptr->rotation_counter + 1;
1134
    } else {
1135
        cube_data_ptr->rotation_counter = (cube_data_ptr->rotation_counter == 0)
1136
                ? CUBE_ROTATIONS - 1 : cube_data_ptr->rotation_counter - 1;
1137
    }
206 Kevin 1138
}
1139
 
264 Kevin 1140
void Cube_Shift_Row(uint8_t direction) {
1141
    // Shifts the display by an entire row
1142
    int i, j, k;
1143
    if (direction) {
1144
        // Shift values in each row by one
1145
        for (i = CUBE_ROW_COUNT - 1; i >= 0; i--) {   // Row
1146
            for (j = 0; j < CUBE_COLUMN_COUNT; j++) {
1147
                for (k = 0; k < CUBE_LAYER_COUNT; k++) {
1148
                    Cube_Move_Pixel(k, i - 1, j, k, i, j);
1149
                }
1150
            }
1151
        }
1152
    } else {
1153
        for (i = 0; i < CUBE_ROW_COUNT - 1; i++) {
1154
            for (j = 0; j < CUBE_COLUMN_COUNT; j++) {
1155
                for (k = 0; k < CUBE_LAYER_COUNT; k++) {
1156
                    Cube_Move_Pixel(k, i + 1, j, k, i, j);
1157
                }
1158
            }
1159
        }
1160
    }
1161
}
1162
 
1163
void Cube_Shift_Waterfall(uint8_t *values) {
1164
    // Takes an array of 8 values and sets them to the column height
1165
    // Each column is set to a manually specified color
1166
    uint8_t i, j;
1167
    uint8_t update_row = CUBE_ROW_COUNT - 1;
1168
 
1169
    // First shift the rows
1170
    Cube_Shift_Row(0);
1171
 
1172
    // Then update the empty row
1173
    for (i = 0; i < CUBE_COLUMN_COUNT; i++) {
1174
        for (j = 0; j < CUBE_LAYER_COUNT; j++) {
268 Kevin 1175
            if (j < values[i] % 9) {
264 Kevin 1176
                // Specify the color for each column
1177
                if (i == 0)
1178
                    Cube_Set_Pixel(j, update_row, i, RED);
1179
                else if (i == 1)
1180
                    Cube_Set_Pixel(j, update_row, i, ORANGE);
1181
                else if (i == 2)
1182
                    Cube_Set_Pixel(j, update_row, i, YELLOW);
1183
                else if (i == 3)
1184
                    Cube_Set_Pixel(j, update_row, i, GREEN);
1185
                else if (i == 4)
1186
                    Cube_Set_Pixel(j, update_row, i, TEAL);
1187
                else if (i == 5)
1188
                    Cube_Set_Pixel(j, update_row, i, BLUE);
1189
                else if (i == 6)
1190
                    Cube_Set_Pixel(j, update_row, i, PURPLE);
1191
                else
1192
                    Cube_Set_Pixel(j, update_row, i, WHITE);
1193
            } else {
1194
                Cube_Set_Pixel(j, update_row, i, CLEAR);
1195
            }
1196
        }
1197
    }
1198
}
1199
 
1200
void Cube_Shift_Waterfall2(uint8_t *values) {
1201
    // Takes an array of 8 values and sets them to the column height
1202
    // Each layer is set to a manually specified color
1203
    uint8_t i, j;
1204
    uint8_t update_row = CUBE_ROW_COUNT - 1;
1205
 
1206
    // First shift the rows
1207
    Cube_Shift_Row(0);
1208
 
1209
    // Then update the empty row
1210
    for (i = 0; i < CUBE_COLUMN_COUNT; i++) {
1211
        for (j = 0; j < CUBE_LAYER_COUNT; j++) {
268 Kevin 1212
            if (j < values[i] % 9) {
264 Kevin 1213
                // Specify the color for each layer
1214
                if (j == 7)
1215
                    Cube_Set_Pixel(j, update_row, i, RED);
1216
                else if (j == 6)
1217
                    Cube_Set_Pixel(j, update_row, i, ORANGE);
1218
                else if (j == 5)
1219
                    Cube_Set_Pixel(j, update_row, i, YELLOW);
1220
                else if (j == 4)
1221
                    Cube_Set_Pixel(j, update_row, i, GREEN);
1222
                else if (j == 3)
1223
                    Cube_Set_Pixel(j, update_row, i, TEAL);
1224
                else if (j == 2)
1225
                    Cube_Set_Pixel(j, update_row, i, BLUE);
1226
                else if (j == 1)
1227
                    Cube_Set_Pixel(j, update_row, i, PURPLE);
1228
                else
1229
                    Cube_Set_Pixel(j, update_row, i, WHITE);
1230
            } else {
1231
                Cube_Set_Pixel(j, update_row, i, CLEAR);
1232
            }
1233
        }
1234
    }
1235
}
1236
 
212 Kevin 1237
///////////////////////////////
1238
// Overlay control functions //
1239
///////////////////////////////
206 Kevin 1240
 
1241
void Cube_Overlay_Clear(void) {
231 Kevin 1242
    uint16_t i,j;
1243
    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
1244
        for (j = 0; j < GCS_LAYER_SIZE; j++) {
206 Kevin 1245
            cube_data_ptr->GCS_OVERLAY[i][j] = 0x00;
231 Kevin 1246
        }
1247
    }
206 Kevin 1248
}
1249
 
231 Kevin 1250
void Cube_Overlay_Set_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t R, uint16_t G, uint16_t B) {
206 Kevin 1251
    // Set the specified pixel to the given color
1252
    R &= 0x0FFF;
1253
    G &= 0x0FFF;
1254
    B &= 0x0FFF;
231 Kevin 1255
    uint16_t var = row * GCS_REG_SIZE + (column / 2 * 9);
206 Kevin 1256
    switch (column % 2) {
1257
        case 0:
1258
            cube_data_ptr->GCS_OVERLAY[layer][var+0] = R & 0xFF;
1259
            cube_data_ptr->GCS_OVERLAY[layer][var+1] = (G << 4) | (R >> 8);
1260
            cube_data_ptr->GCS_OVERLAY[layer][var+2] = G >> 4;
1261
            cube_data_ptr->GCS_OVERLAY[layer][var+3] = B & 0xFF;
1262
            cube_data_ptr->GCS_OVERLAY[layer][var+4] = (cube_data_ptr->GCS_OVERLAY[layer][var+4] & 0xF0) | (B >> 8);
1263
            break;
1264
        case 1:
1265
            cube_data_ptr->GCS_OVERLAY[layer][var+4] = (cube_data_ptr->GCS_OVERLAY[layer][var+4] & 0x0F) | (R << 4);
1266
            cube_data_ptr->GCS_OVERLAY[layer][var+5] = R >> 4;
1267
            cube_data_ptr->GCS_OVERLAY[layer][var+6] = G & 0xFF;
1268
            cube_data_ptr->GCS_OVERLAY[layer][var+7] = (B << 4) | (G >> 8);
1269
            cube_data_ptr->GCS_OVERLAY[layer][var+8] = B >> 4;
1270
            break;
1271
    }
1272
}
1273
 
231 Kevin 1274
void Cube_Overlay_Get_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t* R, uint16_t* G, uint16_t* B) {
1275
    uint16_t var = row * GCS_REG_SIZE + (column / 2 * 9);
206 Kevin 1276
    switch (column % 2) {
1277
        // Concatenate lower byte and upper byte of each color channel
1278
        case 0:
1279
            *R = cube_data_ptr->GCS_OVERLAY[layer][var+0] | ((cube_data_ptr->GCS_OVERLAY[layer][var+1] & 0x0F) << 8);
1280
            *G = (cube_data_ptr->GCS_OVERLAY[layer][var+1] >> 4) | (cube_data_ptr->GCS_OVERLAY[layer][var+2] << 4);
1281
            *B = cube_data_ptr->GCS_OVERLAY[layer][var+3] | ((cube_data_ptr->GCS_OVERLAY[layer][var+4] & 0x0F) << 8);
1282
            break;
1283
        case 1:
1284
            *R = (cube_data_ptr->GCS_OVERLAY[layer][var+4] >> 4) | (cube_data_ptr->GCS_OVERLAY[layer][var+5] << 4);
1285
            *G = cube_data_ptr->GCS_OVERLAY[layer][var+6] | ((cube_data_ptr->GCS_OVERLAY[layer][var+7] & 0x0F) << 8);
1286
            *B = (cube_data_ptr->GCS_OVERLAY[layer][var+7] >> 4) | (cube_data_ptr->GCS_OVERLAY[layer][var+8] << 4);
1287
            break;
1288
    }
1289
}
1290
 
231 Kevin 1291
void Cube_Overlay_Move_Pixel(uint8_t layer1, uint8_t row1, uint8_t column1, uint8_t layer2, uint8_t row2, uint8_t column2) {
206 Kevin 1292
    // Copies data from pixel 1 to pixel 2
1293
    // Note: destination pixel value is overwritten
231 Kevin 1294
    uint16_t prev_R, prev_G, prev_B;
206 Kevin 1295
    Cube_Overlay_Get_Pixel(layer1, row1, column1, &prev_R, &prev_G, &prev_B);
1296
    Cube_Overlay_Set_Pixel(layer2, row2, column2, prev_R, prev_G, prev_B);
1297
}
1298
 
231 Kevin 1299
void Cube_Overlay_Rotate_Shell(uint8_t shell, uint8_t direction) {
206 Kevin 1300
    // Shell is the layer to rotate, with the outermost being 0
231 Kevin 1301
    uint8_t layer;
1302
    uint16_t origin_R, origin_G, origin_B;;
206 Kevin 1303
    for (layer = 0; layer < CUBE_LAYER_COUNT; layer++) {
1304
        if (direction) {
1305
            switch(shell) {
1306
                case 0:
1307
                    // Rotate outermost layer
1308
                    Cube_Overlay_Get_Pixel(layer, 0, 0, &origin_R, &origin_G, &origin_B);
1309
                    Cube_Overlay_Move_Pixel(layer, 0, 1, layer, 0, 0);
1310
                    Cube_Overlay_Move_Pixel(layer, 0, 2, layer, 0, 1);
1311
                    Cube_Overlay_Move_Pixel(layer, 0, 3, layer, 0, 2);
1312
                    Cube_Overlay_Move_Pixel(layer, 0, 4, layer, 0, 3);
1313
                    Cube_Overlay_Move_Pixel(layer, 0, 5, layer, 0, 4);
1314
                    Cube_Overlay_Move_Pixel(layer, 0, 6, layer, 0, 5);
1315
                    Cube_Overlay_Move_Pixel(layer, 0, 7, layer, 0, 6);
1316
                    Cube_Overlay_Move_Pixel(layer, 1, 7, layer, 0, 7);
1317
                    Cube_Overlay_Move_Pixel(layer, 2, 7, layer, 1, 7);
1318
                    Cube_Overlay_Move_Pixel(layer, 3, 7, layer, 2, 7);
1319
                    Cube_Overlay_Move_Pixel(layer, 4, 7, layer, 3, 7);
1320
                    Cube_Overlay_Move_Pixel(layer, 5, 7, layer, 4, 7);
1321
                    Cube_Overlay_Move_Pixel(layer, 6, 7, layer, 5, 7);
1322
                    Cube_Overlay_Move_Pixel(layer, 7, 7, layer, 6, 7);
1323
                    Cube_Overlay_Move_Pixel(layer, 7, 6, layer, 7, 7);
1324
                    Cube_Overlay_Move_Pixel(layer, 7, 5, layer, 7, 6);
1325
                    Cube_Overlay_Move_Pixel(layer, 7, 4, layer, 7, 5);
1326
                    Cube_Overlay_Move_Pixel(layer, 7, 3, layer, 7, 4);
1327
                    Cube_Overlay_Move_Pixel(layer, 7, 2, layer, 7, 3);
1328
                    Cube_Overlay_Move_Pixel(layer, 7, 1, layer, 7, 2);
1329
                    Cube_Overlay_Move_Pixel(layer, 7, 0, layer, 7, 1);
1330
                    Cube_Overlay_Move_Pixel(layer, 6, 0, layer, 7, 0);
1331
                    Cube_Overlay_Move_Pixel(layer, 5, 0, layer, 6, 0);
1332
                    Cube_Overlay_Move_Pixel(layer, 4, 0, layer, 5, 0);
1333
                    Cube_Overlay_Move_Pixel(layer, 3, 0, layer, 4, 0);
1334
                    Cube_Overlay_Move_Pixel(layer, 2, 0, layer, 3, 0);
1335
                    Cube_Overlay_Move_Pixel(layer, 1, 0, layer, 2, 0);
1336
                    Cube_Overlay_Set_Pixel(layer, 1, 0, origin_R, origin_G, origin_B);
1337
                    break;
1338
                case 1:
1339
                    // Rotate second to outermost layer
1340
                    Cube_Overlay_Get_Pixel(layer, 1, 1, &origin_R, &origin_G, &origin_B);
1341
                    Cube_Overlay_Move_Pixel(layer, 1, 2, layer, 1, 1);
1342
                    Cube_Overlay_Move_Pixel(layer, 1, 3, layer, 1, 2);
1343
                    Cube_Overlay_Move_Pixel(layer, 1, 4, layer, 1, 3);
1344
                    Cube_Overlay_Move_Pixel(layer, 1, 5, layer, 1, 4);
1345
                    Cube_Overlay_Move_Pixel(layer, 1, 6, layer, 1, 5);
1346
                    Cube_Overlay_Move_Pixel(layer, 2, 6, layer, 1, 6);
1347
                    Cube_Overlay_Move_Pixel(layer, 3, 6, layer, 2, 6);
1348
                    Cube_Overlay_Move_Pixel(layer, 4, 6, layer, 3, 6);
1349
                    Cube_Overlay_Move_Pixel(layer, 5, 6, layer, 4, 6);
1350
                    Cube_Overlay_Move_Pixel(layer, 6, 6, layer, 5, 6);
1351
                    Cube_Overlay_Move_Pixel(layer, 6, 5, layer, 6, 6);
1352
                    Cube_Overlay_Move_Pixel(layer, 6, 4, layer, 6, 5);
1353
                    Cube_Overlay_Move_Pixel(layer, 6, 3, layer, 6, 4);
1354
                    Cube_Overlay_Move_Pixel(layer, 6, 2, layer, 6, 3);
1355
                    Cube_Overlay_Move_Pixel(layer, 6, 1, layer, 6, 2);
1356
                    Cube_Overlay_Move_Pixel(layer, 5, 1, layer, 6, 1);
1357
                    Cube_Overlay_Move_Pixel(layer, 4, 1, layer, 5, 1);
1358
                    Cube_Overlay_Move_Pixel(layer, 3, 1, layer, 4, 1);
1359
                    Cube_Overlay_Move_Pixel(layer, 2, 1, layer, 3, 1);
1360
                    Cube_Overlay_Set_Pixel(layer, 2, 1, origin_R, origin_G, origin_B);
1361
                    break;
1362
                case 2:
1363
                    // Rotate second to innermost layer
1364
                    Cube_Overlay_Get_Pixel(layer, 2, 2, &origin_R, &origin_G, &origin_B);
1365
                    Cube_Overlay_Move_Pixel(layer, 2, 3, layer, 2, 2);
1366
                    Cube_Overlay_Move_Pixel(layer, 2, 4, layer, 2, 3);
1367
                    Cube_Overlay_Move_Pixel(layer, 2, 5, layer, 2, 4);
1368
                    Cube_Overlay_Move_Pixel(layer, 3, 5, layer, 2, 5);
1369
                    Cube_Overlay_Move_Pixel(layer, 4, 5, layer, 3, 5);
1370
                    Cube_Overlay_Move_Pixel(layer, 5, 5, layer, 4, 5);
1371
                    Cube_Overlay_Move_Pixel(layer, 5, 4, layer, 5, 5);
1372
                    Cube_Overlay_Move_Pixel(layer, 5, 3, layer, 5, 4);
1373
                    Cube_Overlay_Move_Pixel(layer, 5, 2, layer, 5, 3);
1374
                    Cube_Overlay_Move_Pixel(layer, 4, 2, layer, 5, 2);
1375
                    Cube_Overlay_Move_Pixel(layer, 3, 2, layer, 4, 2);
1376
                    Cube_Overlay_Set_Pixel(layer, 3, 2, origin_R, origin_G, origin_B);
1377
                    break;
1378
                case 3:
1379
                    // Rotate innermost layer
1380
                    Cube_Overlay_Get_Pixel(layer, 3, 3, &origin_R, &origin_G, &origin_B);
1381
                    Cube_Overlay_Move_Pixel(layer, 3, 4, layer, 3, 3);
1382
                    Cube_Overlay_Move_Pixel(layer, 4, 4, layer, 3, 4);
1383
                    Cube_Overlay_Move_Pixel(layer, 4, 3, layer, 4, 4);
1384
                    Cube_Overlay_Set_Pixel(layer, 4, 3, origin_R, origin_G, origin_B);
1385
                    break;
1386
            }
1387
        } else {
1388
            switch(shell) {
1389
                case 0:
1390
                    // Rotate outermost layer
1391
                    Cube_Overlay_Get_Pixel(layer, 0, 0, &origin_R, &origin_G, &origin_B);
1392
                    Cube_Overlay_Move_Pixel(layer, 1, 0, layer, 0, 0);
1393
                    Cube_Overlay_Move_Pixel(layer, 2, 0, layer, 1, 0);
1394
                    Cube_Overlay_Move_Pixel(layer, 3, 0, layer, 2, 0);
1395
                    Cube_Overlay_Move_Pixel(layer, 4, 0, layer, 3, 0);
1396
                    Cube_Overlay_Move_Pixel(layer, 5, 0, layer, 4, 0);
1397
                    Cube_Overlay_Move_Pixel(layer, 6, 0, layer, 5, 0);
1398
                    Cube_Overlay_Move_Pixel(layer, 7, 0, layer, 6, 0);
1399
                    Cube_Overlay_Move_Pixel(layer, 7, 1, layer, 7, 0);
1400
                    Cube_Overlay_Move_Pixel(layer, 7, 2, layer, 7, 1);
1401
                    Cube_Overlay_Move_Pixel(layer, 7, 3, layer, 7, 2);
1402
                    Cube_Overlay_Move_Pixel(layer, 7, 4, layer, 7, 3);
1403
                    Cube_Overlay_Move_Pixel(layer, 7, 5, layer, 7, 4);
1404
                    Cube_Overlay_Move_Pixel(layer, 7, 6, layer, 7, 5);
1405
                    Cube_Overlay_Move_Pixel(layer, 7, 7, layer, 7, 6);
1406
                    Cube_Overlay_Move_Pixel(layer, 6, 7, layer, 7, 7);
1407
                    Cube_Overlay_Move_Pixel(layer, 5, 7, layer, 6, 7);
1408
                    Cube_Overlay_Move_Pixel(layer, 4, 7, layer, 5, 7);
1409
                    Cube_Overlay_Move_Pixel(layer, 3, 7, layer, 4, 7);
1410
                    Cube_Overlay_Move_Pixel(layer, 2, 7, layer, 3, 7);
1411
                    Cube_Overlay_Move_Pixel(layer, 1, 7, layer, 2, 7);
1412
                    Cube_Overlay_Move_Pixel(layer, 0, 7, layer, 1, 7);
1413
                    Cube_Overlay_Move_Pixel(layer, 0, 6, layer, 0, 7);
1414
                    Cube_Overlay_Move_Pixel(layer, 0, 5, layer, 0, 6);
1415
                    Cube_Overlay_Move_Pixel(layer, 0, 4, layer, 0, 5);
1416
                    Cube_Overlay_Move_Pixel(layer, 0, 3, layer, 0, 4);
1417
                    Cube_Overlay_Move_Pixel(layer, 0, 2, layer, 0, 3);
1418
                    Cube_Overlay_Move_Pixel(layer, 0, 1, layer, 0, 2);
1419
                    Cube_Overlay_Set_Pixel(layer, 0, 1, origin_R, origin_G, origin_B);
1420
                    break;
1421
                case 1:
1422
                    // Rotate second to outermost layer
1423
                    Cube_Overlay_Get_Pixel(layer, 1, 1, &origin_R, &origin_G, &origin_B);
1424
                    Cube_Overlay_Move_Pixel(layer, 2, 1, layer, 1, 1);
1425
                    Cube_Overlay_Move_Pixel(layer, 3, 1, layer, 2, 1);
1426
                    Cube_Overlay_Move_Pixel(layer, 4, 1, layer, 3, 1);
1427
                    Cube_Overlay_Move_Pixel(layer, 5, 1, layer, 4, 1);
1428
                    Cube_Overlay_Move_Pixel(layer, 6, 1, layer, 5, 1);
1429
                    Cube_Overlay_Move_Pixel(layer, 6, 2, layer, 6, 1);
1430
                    Cube_Overlay_Move_Pixel(layer, 6, 3, layer, 6, 2);
1431
                    Cube_Overlay_Move_Pixel(layer, 6, 4, layer, 6, 3);
1432
                    Cube_Overlay_Move_Pixel(layer, 6, 5, layer, 6, 4);
1433
                    Cube_Overlay_Move_Pixel(layer, 6, 6, layer, 6, 5);
1434
                    Cube_Overlay_Move_Pixel(layer, 5, 6, layer, 6, 6);
1435
                    Cube_Overlay_Move_Pixel(layer, 4, 6, layer, 5, 6);
1436
                    Cube_Overlay_Move_Pixel(layer, 3, 6, layer, 4, 6);
1437
                    Cube_Overlay_Move_Pixel(layer, 2, 6, layer, 3, 6);
1438
                    Cube_Overlay_Move_Pixel(layer, 1, 6, layer, 2, 6);
1439
                    Cube_Overlay_Move_Pixel(layer, 1, 5, layer, 1, 6);
1440
                    Cube_Overlay_Move_Pixel(layer, 1, 4, layer, 1, 5);
1441
                    Cube_Overlay_Move_Pixel(layer, 1, 3, layer, 1, 4);
1442
                    Cube_Overlay_Move_Pixel(layer, 1, 2, layer, 1, 3);
1443
                    Cube_Overlay_Set_Pixel(layer, 1, 2, origin_R, origin_G, origin_B);
1444
                    break;
1445
                case 2:
1446
                    // Rotate second to innermost layer
1447
                    Cube_Overlay_Get_Pixel(layer, 2, 2, &origin_R, &origin_G, &origin_B);
1448
                    Cube_Overlay_Move_Pixel(layer, 3, 2, layer, 2, 2);
1449
                    Cube_Overlay_Move_Pixel(layer, 4, 2, layer, 3, 2);
1450
                    Cube_Overlay_Move_Pixel(layer, 5, 2, layer, 4, 2);
1451
                    Cube_Overlay_Move_Pixel(layer, 5, 3, layer, 5, 2);
1452
                    Cube_Overlay_Move_Pixel(layer, 5, 4, layer, 5, 3);
1453
                    Cube_Overlay_Move_Pixel(layer, 5, 5, layer, 5, 4);
1454
                    Cube_Overlay_Move_Pixel(layer, 4, 5, layer, 5, 5);
1455
                    Cube_Overlay_Move_Pixel(layer, 3, 5, layer, 4, 5);
1456
                    Cube_Overlay_Move_Pixel(layer, 2, 5, layer, 3, 5);
1457
                    Cube_Overlay_Move_Pixel(layer, 2, 4, layer, 2, 5);
1458
                    Cube_Overlay_Move_Pixel(layer, 2, 3, layer, 2, 4);
1459
                    Cube_Overlay_Set_Pixel(layer, 2, 3, origin_R, origin_G, origin_B);
1460
                    break;
1461
                case 3:
1462
                    // Rotate innermost layer
1463
                    Cube_Overlay_Get_Pixel(layer, 3, 3, &origin_R, &origin_G, &origin_B);
1464
                    Cube_Overlay_Move_Pixel(layer, 4, 3, layer, 3, 3);
1465
                    Cube_Overlay_Move_Pixel(layer, 4, 4, layer, 4, 3);
1466
                    Cube_Overlay_Move_Pixel(layer, 3, 4, layer, 4, 4);
1467
                    Cube_Overlay_Set_Pixel(layer, 3, 4, origin_R, origin_G, origin_B);
1468
                    break;
1469
            }
1470
        }
1471
    }
1472
}
1473
 
212 Kevin 1474
////////////////////////////
1475
// Text control functions //
1476
////////////////////////////
206 Kevin 1477
 
231 Kevin 1478
void Cube_Text_Init(uint8_t *string, uint8_t length, uint16_t R, uint16_t G, uint16_t B) {
206 Kevin 1479
    // Ensure that the length of the string does not exceed the storage buffer
1480
    if (length > CUBE_STRING_MAX_LENGTH) length = CUBE_STRING_MAX_LENGTH;
1481
 
215 Kevin 1482
    Cube_Overlay_Clear();
1483
 
206 Kevin 1484
    // Copy the passed data into the buffer
231 Kevin 1485
    uint8_t i;
206 Kevin 1486
    for (i = 0; i < length; i++)
1487
        cube_data_ptr->string[i] = string[i];
1488
    cube_data_ptr->string_length = length;
1489
    cube_data_ptr->string_index = 0;
1490
    cube_data_ptr->string_line = 0;
1491
    cube_data_ptr->string_R = R;
1492
    cube_data_ptr->string_G = G;
1493
    cube_data_ptr->string_B = B;
1494
}
1495
 
266 Kevin 1496
void Cube_Text_Update(void) {
231 Kevin 1497
    uint8_t layer;
1498
    uint16_t line;
206 Kevin 1499
 
1500
    // Rotate before drawing the new line at (0,0)
1501
    Cube_Overlay_Rotate_Shell(0, 0);
1502
 
266 Kevin 1503
    // Get the next vertical line of the character currently being drawn
206 Kevin 1504
    if (cube_data_ptr->string_line == 5) {
266 Kevin 1505
        line = 0x0; // Leave a space between characters
206 Kevin 1506
    } else {
1507
        line = font[(cube_data_ptr->string[cube_data_ptr->string_index] * 5)
1508
                + cube_data_ptr->string_line];
1509
    }
1510
 
1511
    // Draw the line onto (0,0) using the specified color
231 Kevin 1512
    for (layer = 8; layer != 0; layer--) {
206 Kevin 1513
        if (line & 0x1) {
231 Kevin 1514
            Cube_Overlay_Set_Pixel(layer-1, 0, 0, cube_data_ptr->string_R,
206 Kevin 1515
                    cube_data_ptr->string_G, cube_data_ptr->string_B);
1516
        } else {
231 Kevin 1517
            Cube_Overlay_Set_Pixel(layer-1, 0, 0, 0x00, 0x00, 0x00);
206 Kevin 1518
        }
1519
        line >>= 1;
1520
    }
1521
 
266 Kevin 1522
    // Increment the vertical line and the character as needed
206 Kevin 1523
    if (cube_data_ptr->string_line == 5) {
1524
        cube_data_ptr->string_line = 0;
1525
        if (cube_data_ptr->string_index == cube_data_ptr->string_length-1) {
1526
            cube_data_ptr->string_index = 0;
1527
        } else {
1528
            cube_data_ptr->string_index += 1;
1529
        }
1530
    } else {
1531
        cube_data_ptr->string_line += 1;
1532
    }
212 Kevin 1533
}
1534
 
268 Kevin 1535
void Cube_Text_Insert(uint8_t c, uint16_t R, uint16_t G, uint16_t B, uint16_t delay) {
1536
    // Save the character to insert
1537
    cube_data_ptr->string[0] = c;
1538
    cube_data_ptr->string_length = 1;
1539
    cube_data_ptr->string_line = 0;
1540
    cube_data_ptr->string_R = R;
1541
    cube_data_ptr->string_G = G;
1542
    cube_data_ptr->string_B = B;
1543
 
1544
    if (delay == 0) {
1545
        int i;
1546
        for (i = 0; i < 6; i++) {
1547
            Cube_Text_Single_Char_Interupt();
1548
        }
1549
    } else {
1550
        // Start a timer to update the overlay with the inserted character
1551
        TIMER4_Stop();
1552
        TIMER4_Init(NULL, NULL, &Cube_Text_Single_Char_Interupt, delay);
1553
        TIMER4_Start();
1554
    }
1555
}
1556
 
1557
void Cube_Text_Single_Char_Interupt(void) {
266 Kevin 1558
    uint8_t layer;
268 Kevin 1559
    uint8_t line;
266 Kevin 1560
 
268 Kevin 1561
    // Rotate before drawing the new line at (0,0)
1562
    Cube_Overlay_Rotate_Shell(0, 0);
266 Kevin 1563
 
268 Kevin 1564
    // Get the next vertical line of the character currently being drawn
1565
    if (cube_data_ptr->string_line == 0) {
1566
        line = 0x0; // Leave a space between characters
1567
    } else {
1568
        line = font[(cube_data_ptr->string[0] * 5) + cube_data_ptr->string_line - 1];
1569
    }
266 Kevin 1570
 
268 Kevin 1571
    // Draw the line onto (0,0) using the specified color
1572
    for (layer = 8; layer != 0; layer--) {
1573
        if (line & 0x1) {
1574
            Cube_Overlay_Set_Pixel(layer-1, 0, 0, cube_data_ptr->string_R,
1575
                    cube_data_ptr->string_G, cube_data_ptr->string_B);
266 Kevin 1576
        } else {
268 Kevin 1577
            Cube_Overlay_Set_Pixel(layer-1, 0, 0, 0x00, 0x00, 0x00);
266 Kevin 1578
        }
268 Kevin 1579
        line >>= 1;
1580
    }
266 Kevin 1581
 
268 Kevin 1582
    // Increment the vertical line or stop the timer as needed
1583
    if (cube_data_ptr->string_line == 5) {
1584
        TIMER4_Stop();
1585
    } else {
1586
        cube_data_ptr->string_line += 1;
266 Kevin 1587
    }
1588
}
1589
 
1590
void Cube_Text_Interrupt(void) {
1591
    Cube_Text_Update();
1592
}
1593
 
212 Kevin 1594
/////////////////////////////////////////////
1595
// Functions for processing streaming data //
1596
/////////////////////////////////////////////
1597
 
231 Kevin 1598
void Cube_Data_In(uint8_t c) {
1599
    // Reset upon receiving the start int8_t
212 Kevin 1600
    if (c == CUBE_START_CHAR) {
1601
        cube_data_ptr->frame_length = 0;
1602
        cube_data_ptr->frame_index = 0;
1603
        cube_data_ptr->frame_checksum = 0;
1604
        cube_data_ptr->frame_command = 0;
215 Kevin 1605
        cube_data_ptr->frame_escape = 0;
212 Kevin 1606
        cube_data_ptr->frame_state = READ_LENGTH_MSB;
215 Kevin 1607
        return;
1608
    }
231 Kevin 1609
    // If the input is the escape int8_t, XOR the next int8_t received
215 Kevin 1610
    if (c == CUBE_ESCAPE_CHAR) {
1611
        cube_data_ptr->frame_escape = 1;
1612
        return;
1613
    }
231 Kevin 1614
    // XOR the input int8_t if needed
215 Kevin 1615
    if (cube_data_ptr->frame_escape) {
1616
        c ^= CUBE_ESCAPE_XOR;
1617
        cube_data_ptr->frame_escape = 0;
1618
    }
1619
    // Process data
1620
    switch (cube_data_ptr->frame_state) {
1621
        case IDLE:
266 Kevin 1622
            // Reflect the character back to the transmitter
215 Kevin 1623
            UART1_Write(&c, 1);
1624
            break;
1625
        case READ_LENGTH_MSB: // Save MSB of length
1626
            cube_data_ptr->frame_length |= (c << 8);
1627
            cube_data_ptr->frame_state = READ_LENGTH_LSB;
1628
            break;
1629
        case READ_LENGTH_LSB: // Save LSB of length
1630
            cube_data_ptr->frame_length |= c;
1631
            cube_data_ptr->frame_state = READ_COMMAND;
1632
            break;
1633
        case READ_COMMAND: // Store the command byte
1634
            cube_data_ptr->frame_checksum += c;
1635
            cube_data_ptr->frame_command = c;
1636
            if (cube_data_ptr->frame_length == 1)
1637
                cube_data_ptr->frame_state = READ_CHECKSUM;
1638
            else
212 Kevin 1639
                cube_data_ptr->frame_state = READ_DATA;
215 Kevin 1640
            break;
1641
        case READ_DATA: // Read the passed data into the buffer
1642
            cube_data_ptr->frame_checksum += c;
1643
            cube_data_ptr->frame_buffer[cube_data_ptr->frame_index] = c;
1644
            cube_data_ptr->frame_index++;
1645
            if (cube_data_ptr->frame_index == cube_data_ptr->frame_length - 1)
1646
                cube_data_ptr->frame_state = READ_CHECKSUM;
1647
            break;
1648
        case READ_CHECKSUM: // Process frame if checksum is valid
1649
            cube_data_ptr->frame_checksum = 0xFF - cube_data_ptr->frame_checksum;
1650
            if (cube_data_ptr->frame_checksum == c) {
1651
                Cube_Data_In_Process_Frame();
1652
            }
1653
            cube_data_ptr->frame_state = IDLE;
1654
            cube_data_ptr->frame_index = 0;
1655
            cube_data_ptr->frame_length = 0;
1656
            break;
1657
        default:
1658
            break;
212 Kevin 1659
    }
1660
}
1661
 
1662
void Cube_Data_In_Process_Frame(void) {
215 Kevin 1663
    // Here we process received frames depending on the command
231 Kevin 1664
    uint8_t *frame = cube_data_ptr->frame_buffer;
212 Kevin 1665
    switch (cube_data_ptr->frame_command) {
215 Kevin 1666
        case CUBE_COMMAND_SET_BC:
1667
            TIMER5_Stop();
1668
            Delay_MS(1); // Need to wait for all SPI writes to complete
1669
            Cube_Write_DCS(frame[0]);
1670
            TIMER5_Start();
1671
            break;
1672
        case CUBE_COMMAND_CLEAR:
1673
            Cube_Clear();
1674
            break;
212 Kevin 1675
        case CUBE_COMMAND_SET_PIXEL:
1676
            Cube_Set_Pixel(frame[0], frame[1], frame[2], frame[3], frame[4], frame[5]);
1677
            break;
216 Kevin 1678
        case CUBE_COMMAND_SET_ALL:
1679
            Cube_Data_Direct_Write_All(&frame[0]);
215 Kevin 1680
            break;
1681
        case CUBE_COMMAND_START_TEXT:
1682
            Cube_Text_Init(&frame[3], cube_data_ptr->frame_length - 4, frame[0], frame[1], frame[2]);
1683
            TIMER4_Start();
1684
            break;
1685
        case CUBE_COMMAND_STOP_TEXT:
1686
            TIMER4_Stop();
1687
            Cube_Overlay_Clear();
1688
            break;
212 Kevin 1689
        default:
1690
            break;
1691
    }
215 Kevin 1692
}
1693
 
231 Kevin 1694
void Cube_Data_Direct_Write_All(uint8_t *buffer) {
216 Kevin 1695
    memcpy(cube_data_ptr->GCS, buffer, CUBE_LAYER_COUNT * GCS_LAYER_SIZE);
255 Kevin 1696
}
1697
 
1698
void Cube_Ethernet_Frame_In(void) {
1699
    uint8_t i,j,k;
261 Kevin 1700
    uint8_t buffer[2048] = {0};
255 Kevin 1701
    uint16_t length;
1702
 
1703
    // Read and process the ethernet packet
261 Kevin 1704
    if (!ETH_Read_Packet(buffer, &length)) {
1705
        // Check the opcode (first byte) to determine what to do
264 Kevin 1706
        if (buffer[0] == CUBE_ETH_RESET) {  // 0x1 - Reset into Ethernet mode
255 Kevin 1707
            Reset_Board(BOARD_MODE_ETHERNET);
264 Kevin 1708
        } else if (Get_Board_State() == BOARD_MODE_ETHERNET) {
266 Kevin 1709
            ClearWDT();
264 Kevin 1710
            if (buffer[0] == CUBE_EHT_IDLE) {   // 0x2 - Reset back to idle mode
1711
                Reset_Board(BOARD_MODE_IDLE);
1712
            } else if (buffer[0] == CUBE_ETH_CLEAR) {   // 0xA
1713
                Cube_Clear();
1714
            } else if (buffer[0] == CUBE_ETH_DCS) {     // 0xB
1715
                // Byte 1 = global brightness value
1716
                Cube_Write_DCS(buffer[1]);
1717
            } else if (buffer[0] == CUBE_ETH_ROTATE) {  // 0xC
1718
                // Byte 1 = directon to rotate
1719
                Cube_Rotate(buffer[1]);
1720
            } else if (buffer[0] == CUBE_ETH_ROTATE_LAYER) {    // 0xD
1721
                // Byte 1 = layer to rotate
1722
                // Byte 2 = direction to rotate
1723
                Cube_Rotate_Shell(buffer[1], buffer[2]);
1724
            } else if (buffer[0] == CUBE_ETH_WRITE_ALL) {       // 0x10
1725
                // Byte 1+ = pixel color data (R/G/B)
1726
                if (length == 0x0601) {
1727
                    uint16_t index = 1;
1728
                    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
1729
                        for (j = 0; j < CUBE_COLUMN_COUNT; j++) {
1730
                            for (k = 0; k < CUBE_ROW_COUNT; k++) {
1731
                                Cube_Set_Pixel(i, k, j, buffer[index], buffer[index+1], buffer[index+2]);
1732
                                index = index + 3;
1733
                            }
263 Kevin 1734
                        }
255 Kevin 1735
                    }
1736
                }
264 Kevin 1737
            } else if (buffer[0] == CUBE_ETH_WRITE_PIXEL) {     // 0x11
1738
                // Byte 1 = row index
1739
                // Byte 2 = column index
1740
                // Byte 3 = layer index
1741
                // Byte 4 = red channel
1742
                // Byte 5 = green channel
1743
                // Byte 6 = blue channel
1744
                Cube_Set_Pixel(buffer[3], buffer[1], buffer[2], buffer[4], buffer[5], buffer[6]);
1745
            } else if (buffer[0] == CUBE_ETH_WRITE_CHANNEL) {   // 0x12
1746
                // Byte 1 = color channel, 0 = red, 1 = green, 2 = blue
1747
                // Byte 2+ = color data
1748
                uint16_t r, g, b;
1749
                uint16_t index = 2;
1750
                if (buffer[1] % 3 == 0) {
1751
                    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
1752
                        for (j = 0; j < CUBE_ROW_COUNT; j++) {
1753
                            for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
1754
//                                Cube_Get_Pixel(i, j, k, &r, &g, &b);
1755
                                Cube_Set_Pixel(i, j, k, buffer[index], 0x00, 0x00);
1756
                                index++;
1757
                            }
1758
                        }
1759
                    }
1760
                } else if (buffer[1] % 3 == 1) {
1761
                    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
1762
                        for (j = 0; j < CUBE_ROW_COUNT; j++) {
1763
                            for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
1764
                                Cube_Get_Pixel(i, j, k, &r, &g, &b);
1765
                                Cube_Set_Pixel(i, j, k, r, buffer[index], b);
1766
                                index++;
1767
                            }
1768
                        }
1769
                    }
1770
                } else {
1771
                    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
1772
                        for (j = 0; j < CUBE_ROW_COUNT; j++) {
1773
                            for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
1774
                                Cube_Get_Pixel(i, j, k, &r, &g, &b);
1775
                                Cube_Set_Pixel(i, j, k, r, g, buffer[index]);
1776
                                index++;
1777
                            }
1778
                        }
1779
                    }
1780
                }
266 Kevin 1781
            } else if (buffer[0] == CUBE_ETH_WRITE_TEXT_SCROLL) {   // 0x20
264 Kevin 1782
                // Byte 1 = length of string
1783
                // Byte 2 = red channel
1784
                // Byte 3 = green channel
1785
                // Byte 4 = blue channel
1786
                // Byte 5 = update speed (ms)
1787
                // Byte 6+ = text string
1788
                if (buffer[1] != 0) {
266 Kevin 1789
                    TIMER4_Stop();
264 Kevin 1790
                    Cube_Text_Init(&buffer[6], buffer[1], buffer[2], buffer[3], buffer[4]);
1791
                    TIMER4_Init(NULL, NULL, &Cube_Text_Interrupt, buffer[5]);
1792
                    TIMER4_Start();
1793
                } else {
266 Kevin 1794
                    TIMER4_Stop();
264 Kevin 1795
                    Cube_Overlay_Clear();
266 Kevin 1796
                }
1797
            } else if (buffer[0] == CUBE_ETH_WRITE_TEXT_STATIC) {   // 0x21
1798
                // Byte 1 = length of string
1799
                // Byte 2 = red channel
1800
                // Byte 3 = green channel
1801
                // Byte 4 = blue channel
1802
                // Byte 5+ = text string
1803
                if (buffer[1] != 0) {
264 Kevin 1804
                    TIMER4_Stop();
266 Kevin 1805
                    Cube_Text_Init(&buffer[5], buffer[1], buffer[2], buffer[3], buffer[4]);
1806
                    for (i = 0; i < buffer[1] * 5; i++) {
1807
                        Cube_Text_Update();
1808
                    }
1809
                } else {
1810
                    TIMER4_Stop();
1811
                    Cube_Overlay_Clear();
264 Kevin 1812
                }
266 Kevin 1813
            } else if (buffer[0] == CUBE_EHT_WRITE_TEXT_INSERT) {   // 0x22
1814
                // Byte 1 = red channel
1815
                // Byte 2 = green channel
1816
                // Byte 3 = blue channel
268 Kevin 1817
                // Byte 4 = delay x6 between shifts
1818
                // Byte 5 = character
266 Kevin 1819
                TIMER4_Stop();
268 Kevin 1820
                Cube_Text_Insert(buffer[5], buffer[1], buffer[2], buffer[3], buffer[4]);
264 Kevin 1821
            } else if (buffer[0] == CUBE_ETH_WATERFALL) {       // 0x30
1822
                // Byte 1 = height of column 0
1823
                // Byte 2 = height of column 1
1824
                // Byte 3 = height of column 2
1825
                // Byte 4 = height of column 3
1826
                // Byte 5 = height of column 4
1827
                // Byte 6 = height of column 5
1828
                // Byte 7 = height of column 6
1829
                // Byte 8 = height of column 7
1830
                Cube_Shift_Waterfall(&buffer[1]);
1831
            } else if (buffer[0] == CUBE_ETH_SPHERE) {          // 0x31
1832
                // Byte 1 = layer (0 = innermost)
1833
                // Byte 2 = red channel
1834
                // Byte 3 = green channel
1835
                // Byte 4 = blue channel
1836
                Cube_Set_Sphere(buffer[1], buffer[2], buffer[3], buffer[4]);
255 Kevin 1837
            }
1838
        }
1839
    }
264 Kevin 1840
}