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
 
200 Kevin 17
void Cube_Init(CUBE_DATA *data, char BC) {
199 Kevin 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
 
200 Kevin 47
    Cube_Write_DCS(BC);
199 Kevin 48
    Cube_Clear();
49
}
50
 
51
void Cube_Timer_Interrupt(void) {
52
    // Write to the GCS register
53
    SPI1_Write(cube_data_ptr->GCS[current_layer], GCS_LAYER_SIZE, &Cube_GCS_Write_Callback);
54
}
55
 
56
void Cube_DCS_Write_Callback(void) {
57
    // GSLAT must be >7ms after DCS write
58
    Delay_MS(7);
59
    GSLAT = 0;
60
    Cube_Delay();
61
    GSLAT = 1;
62
    Cube_Delay();
63
    GSLAT = 0;
64
}
65
 
66
void Cube_GCS_Write_Callback(void) {
67
    // Disable LED output and latch in written data to GCS
68
    XBLNK = 0;
69
    Cube_Delay();
70
    GSLAT = 1;
71
    // Set the shift register to turn on the current layer
72
    int i;
73
    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
74
        Cube_Delay();
75
        SFT_D = (i == CUBE_LAYER_COUNT - current_layer - 1) ? 1 : 0;
76
        Cube_Delay();
77
        SFT_K = 1;
78
        Cube_Delay();
79
        SFT_K = 0;
80
    }
81
    Cube_Delay();
82
    SFT_S = 1;
83
    Cube_Delay();
84
    SFT_S = 0;
85
    Cube_Delay();
86
    // Enable LED output
87
    XBLNK = 1;
88
    Cube_Delay();
89
    GSLAT = 0;
90
 
91
    current_layer = (current_layer == CUBE_LAYER_COUNT-1) ? 0 : current_layer + 1;
92
}
93
 
200 Kevin 94
void Cube_Write_DCS(char BC) {
95
    if (BC > CUBE_MAX_BRIGHTNESS)
96
        BC = CUBE_MAX_BRIGHTNESS;
97
 
98
    XBLNK = 0;
99
    int i,j;
100
    // Write configuration data to the DC/BC/FC/UD registers
101
    unsigned char DCS[GCS_LAYER_SIZE] = {0};
102
    for (i = 0; i < 8; i++) {
103
        int offset = i * GCS_REG_SIZE;
104
 
105
        for (j = 0; j < 21; j++) {
106
            DCS[offset + j] = 0xFF; // Dot correction
107
        }
108
 
109
        // Warning: do not set BC > 0x6F
110
        DCS[offset + 21] = BC; // Global red brightness
111
        DCS[offset + 22] = BC; // Global green brightness
112
        DCS[offset + 23] = BC; // Global blue brightness
113
 
114
        // DC low range, auto repeat, no timing reset, 8 bit counter mode
115
        DCS[offset + 24] = 0x68; // 0110 1000
116
    }
117
 
118
    GSLAT = 1;
119
    SPI1_Write(DCS, GCS_LAYER_SIZE, &Cube_DCS_Write_Callback);
120
    Delay_MS(8); // Delay until the entire DCS write is finished
121
}
122
 
199 Kevin 123
void Cube_Clear(void) {
124
    int i,j;
125
    for (i = 0; i < CUBE_LAYER_COUNT; i++)
126
        for (j = 0; j < GCS_LAYER_SIZE; j++)
127
            cube_data_ptr->GCS[i][j] = 0x00;
128
}
129
 
130
void Cube_Set_All(int R, int G, int B) {
131
    R &= 0x0FFF;
132
    G &= 0x0FFF;
133
    B &= 0x0FFF;
134
    int i,j,k;
135
    for (i = 0; i < CUBE_LAYER_COUNT; i++) {
136
        for (j = 0; j < CUBE_ROW_COUNT; j++) {
137
            int j_var = j * GCS_REG_SIZE;
138
            for (k = 0; k < 4; k++) {
139
                int k_var = j_var + (k * 9);
140
                cube_data_ptr->GCS[i][k_var+0] = R & 0xFF;;
141
                cube_data_ptr->GCS[i][k_var+1] = (G << 4) | (R >> 8);
142
                cube_data_ptr->GCS[i][k_var+2] = G >> 4;
143
                cube_data_ptr->GCS[i][k_var+3] = B & 0xFF;
144
                cube_data_ptr->GCS[i][k_var+4] = (R << 4) | (B >> 8);
145
                cube_data_ptr->GCS[i][k_var+5] = R >> 4;
146
                cube_data_ptr->GCS[i][k_var+6] = G & 0xFF;
147
                cube_data_ptr->GCS[i][k_var+7] = (B << 4) | (G >> 8);
148
                cube_data_ptr->GCS[i][k_var+8] = B >> 4;
149
            }
150
        }
151
    }
152
}
153
 
154
void Cube_Set_Layer(int layer, int R, int G, int B) {
155
    R &= 0x0FFF;
156
    G &= 0x0FFF;
157
    B &= 0x0FFF;
158
    int i,j;
159
    for (i = 0; i < CUBE_ROW_COUNT; i++) {
160
        int i_var = i * GCS_REG_SIZE;
161
        for (j = 0; j < 4; j++) {
162
            int j_var = i_var + (j * 9);
163
            cube_data_ptr->GCS[layer][j_var+0] = R & 0xFF;;
164
            cube_data_ptr->GCS[layer][j_var+1] = (G << 4) | (R >> 8);
165
            cube_data_ptr->GCS[layer][j_var+2] = G >> 4;
166
            cube_data_ptr->GCS[layer][j_var+3] = B & 0xFF;
167
            cube_data_ptr->GCS[layer][j_var+4] = (R << 4) | (B >> 8);
168
            cube_data_ptr->GCS[layer][j_var+5] = R >> 4;
169
            cube_data_ptr->GCS[layer][j_var+6] = G & 0xFF;
170
            cube_data_ptr->GCS[layer][j_var+7] = (B << 4) | (G >> 8);
171
            cube_data_ptr->GCS[layer][j_var+8] = B >> 4;
172
        }
173
    }
174
}
175
 
176
void Cube_Set_Pixel(int layer, int row, int column, int R, int G, int B) {
177
    R &= 0x0FFF;
178
    G &= 0x0FFF;
179
    B &= 0x0FFF;
180
    int var = row * GCS_REG_SIZE + (column / 2 * 9);
181
    switch (column % 2) {
182
        case 0:
183
            cube_data_ptr->GCS[layer][var+0] = R & 0xFF;
184
            cube_data_ptr->GCS[layer][var+1] = (G << 4) | (R >> 8);
185
            cube_data_ptr->GCS[layer][var+2] = G >> 4;
186
            cube_data_ptr->GCS[layer][var+3] = B & 0xFF;
187
            cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0xF0) | (B >> 8);
188
            break;
189
        case 1:
190
            cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0x0F) | (R << 4);
191
            cube_data_ptr->GCS[layer][var+5] = R >> 4;
192
            cube_data_ptr->GCS[layer][var+6] = G & 0xFF;
193
            cube_data_ptr->GCS[layer][var+7] = (B << 4) | (G >> 8);
194
            cube_data_ptr->GCS[layer][var+8] = B >> 4;
195
            break;
196
    }
197
}