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