Subversion Repositories Code-Repo

Rev

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