Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
199 Kevin 1
#include <xc.h>
2
#include <plib.h>
3
#include "defines.h"
4
#include "CUBE.h"
5
#include "SPI1.h"
6
 
7
static CUBE_DATA *cube_data_ptr;
8
static unsigned char current_layer;
9
 
10
inline void Cube_Delay() {
11
    // Small delay to ensure that latch speeds are < 30Mhz
12
    Nop();
13
    Nop();
14
    Nop();
15
}
16
 
17
void Cube_Init(CUBE_DATA *data) {
18
    cube_data_ptr = data;
19
    current_layer = 0;
20
 
21
    SFT_D = 0;
22
    SFT_S = 0;
23
    SFT_K = 0;
24
    SFT_R = 0;
25
    GSLAT = 0;
26
    XBLNK = 0;
27
 
28
    SFT_D_TRIS = 0;
29
    SFT_S_TRIS = 0;
30
    SFT_K_TRIS = 0;
31
    SFT_R_TRIS = 0;
32
    GSLAT_TRIS = 0;
33
    XBLNK_TRIS = 0;
34
 
35
    // Clear the shift register
36
    Cube_Delay();
37
    SFT_K = 1;
38
    Cube_Delay();
39
    SFT_K = 0;
40
    Cube_Delay();
41
    SFT_S = 1;
42
    Cube_Delay();
43
    SFT_S = 0;
44
    Cube_Delay();
45
    SFT_R = 1;
46
 
47
    int i,j;
48
    // Write configuration data to the DC/BC/FC/UD registers
49
    unsigned char DCS[GCS_LAYER_SIZE] = {0};
50
    for (i = 0; i < 8; i++) {
51
        int offset = i * GCS_REG_SIZE;
52
 
53
        for (j = 0; j < 21; j++) {
54
            DCS[offset + j] = 0xFF; // Dot correction
55
        }
56
 
57
        // Warning: do not set BC > 0x8F
58
        DCS[offset + 21] = 0x1F; // Global red brightness
59
        DCS[offset + 22] = 0x1F; // Global green brightness
60
        DCS[offset + 23] = 0x1F; // Global blue brightness
61
 
62
        // DC low range, auto repeat, no timing reset, 8 bit counter mode
63
        DCS[offset + 24] = 0x68; // 0110 1000
64
    }
65
 
66
    Cube_Clear();
67
 
68
    GSLAT = 1;
69
    SPI1_Write(DCS, GCS_LAYER_SIZE, &Cube_DCS_Write_Callback);
70
    Delay_MS(8); // Delay until the entire DCS write is finished
71
}
72
 
73
void Cube_Timer_Interrupt(void) {
74
    // Write to the GCS register
75
    SPI1_Write(cube_data_ptr->GCS[current_layer], GCS_LAYER_SIZE, &Cube_GCS_Write_Callback);
76
}
77
 
78
void Cube_DCS_Write_Callback(void) {
79
    // GSLAT must be >7ms after DCS write
80
    Delay_MS(7);
81
    GSLAT = 0;
82
    Cube_Delay();
83
    GSLAT = 1;
84
    Cube_Delay();
85
    GSLAT = 0;
86
}
87
 
88
void Cube_GCS_Write_Callback(void) {
89
    // Disable LED output and latch in written data to GCS
90
    XBLNK = 0;
91
    Cube_Delay();
92
    GSLAT = 1;
93
    // Set the shift register to turn on the current layer
94
    int i;
95
    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
96
        Cube_Delay();
97
        SFT_D = (i == CUBE_LAYER_COUNT - current_layer - 1) ? 1 : 0;
98
        Cube_Delay();
99
        SFT_K = 1;
100
        Cube_Delay();
101
        SFT_K = 0;
102
    }
103
    Cube_Delay();
104
    SFT_S = 1;
105
    Cube_Delay();
106
    SFT_S = 0;
107
    Cube_Delay();
108
    // Enable LED output
109
    XBLNK = 1;
110
    Cube_Delay();
111
    GSLAT = 0;
112
 
113
    current_layer = (current_layer == CUBE_LAYER_COUNT-1) ? 0 : current_layer + 1;
114
}
115
 
116
void Cube_Clear(void) {
117
    int i,j;
118
    for (i = 0; i < CUBE_LAYER_COUNT; i++)
119
        for (j = 0; j < GCS_LAYER_SIZE; j++)
120
            cube_data_ptr->GCS[i][j] = 0x00;
121
}
122
 
123
void Cube_Set_All(int R, int G, int B) {
124
    R &= 0x0FFF;
125
    G &= 0x0FFF;
126
    B &= 0x0FFF;
127
    int i,j,k;
128
    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
129
        for (j = 0; j < CUBE_ROW_COUNT; j++) {
130
            int j_var = j * GCS_REG_SIZE;
131
            for (k = 0; k < 4; k++) {
132
                int k_var = j_var + (k * 9);
133
                cube_data_ptr->GCS[i][k_var+0] = R & 0xFF;;
134
                cube_data_ptr->GCS[i][k_var+1] = (G << 4) | (R >> 8);
135
                cube_data_ptr->GCS[i][k_var+2] = G >> 4;
136
                cube_data_ptr->GCS[i][k_var+3] = B & 0xFF;
137
                cube_data_ptr->GCS[i][k_var+4] = (R << 4) | (B >> 8);
138
                cube_data_ptr->GCS[i][k_var+5] = R >> 4;
139
                cube_data_ptr->GCS[i][k_var+6] = G & 0xFF;
140
                cube_data_ptr->GCS[i][k_var+7] = (B << 4) | (G >> 8);
141
                cube_data_ptr->GCS[i][k_var+8] = B >> 4;
142
            }
143
        }
144
    }
145
}
146
 
147
void Cube_Set_Layer(int layer, int R, int G, int B) {
148
    R &= 0x0FFF;
149
    G &= 0x0FFF;
150
    B &= 0x0FFF;
151
    int i,j;
152
    for (i = 0; i < CUBE_ROW_COUNT; i++) {
153
        int i_var = i * GCS_REG_SIZE;
154
        for (j = 0; j < 4; j++) {
155
            int j_var = i_var + (j * 9);
156
            cube_data_ptr->GCS[layer][j_var+0] = R & 0xFF;;
157
            cube_data_ptr->GCS[layer][j_var+1] = (G << 4) | (R >> 8);
158
            cube_data_ptr->GCS[layer][j_var+2] = G >> 4;
159
            cube_data_ptr->GCS[layer][j_var+3] = B & 0xFF;
160
            cube_data_ptr->GCS[layer][j_var+4] = (R << 4) | (B >> 8);
161
            cube_data_ptr->GCS[layer][j_var+5] = R >> 4;
162
            cube_data_ptr->GCS[layer][j_var+6] = G & 0xFF;
163
            cube_data_ptr->GCS[layer][j_var+7] = (B << 4) | (G >> 8);
164
            cube_data_ptr->GCS[layer][j_var+8] = B >> 4;
165
        }
166
    }
167
}
168
 
169
void Cube_Set_Pixel(int layer, int row, int column, int R, int G, int B) {
170
    R &= 0x0FFF;
171
    G &= 0x0FFF;
172
    B &= 0x0FFF;
173
    int var = row * GCS_REG_SIZE + (column / 2 * 9);
174
    switch (column % 2) {
175
        case 0:
176
            cube_data_ptr->GCS[layer][var+0] = R & 0xFF;
177
            cube_data_ptr->GCS[layer][var+1] = (G << 4) | (R >> 8);
178
            cube_data_ptr->GCS[layer][var+2] = G >> 4;
179
            cube_data_ptr->GCS[layer][var+3] = B & 0xFF;
180
            cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0xF0) | (B >> 8);
181
            break;
182
        case 1:
183
            cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0x0F) | (R << 4);
184
            cube_data_ptr->GCS[layer][var+5] = R >> 4;
185
            cube_data_ptr->GCS[layer][var+6] = G & 0xFF;
186
            cube_data_ptr->GCS[layer][var+7] = (B << 4) | (G >> 8);
187
            cube_data_ptr->GCS[layer][var+8] = B >> 4;
188
            break;
189
    }
190
}