Rev 200 | Blame | Last modification | View Log | Download | RSS feed
#include <xc.h>#include <plib.h>#include "defines.h"#include "CUBE.h"#include "SPI1.h"static CUBE_DATA *cube_data_ptr;inline void Cube_Delay() {// Small delay to ensure that latch speeds are < 30MhzNop();Nop();Nop();}void Cube_Init(CUBE_DATA *data, char BC) {cube_data_ptr = data;cube_data_ptr->current_layer = 0;SFT_D = 0;SFT_S = 0;SFT_K = 0;SFT_R = 0;GSLAT = 0;XBLNK = 0;SFT_D_TRIS = 0;SFT_S_TRIS = 0;SFT_K_TRIS = 0;SFT_R_TRIS = 0;GSLAT_TRIS = 0;XBLNK_TRIS = 0;// Clear the shift registerCube_Delay();SFT_K = 1;Cube_Delay();SFT_K = 0;Cube_Delay();SFT_S = 1;Cube_Delay();SFT_S = 0;Cube_Delay();SFT_R = 1;Cube_Write_DCS(BC);Cube_Clear();}void Cube_Timer_Interrupt(void) {// Write to the GCS registerSPI1_Write(cube_data_ptr->GCS[cube_data_ptr->current_layer], GCS_LAYER_SIZE, &Cube_GCS_Write_Callback);}void Cube_DCS_Write_Callback(void) {// GSLAT must be >7ms after DCS writeDelay_MS(7);GSLAT = 0;Cube_Delay();GSLAT = 1;Cube_Delay();GSLAT = 0;}void Cube_GCS_Write_Callback(void) {// Disable LED output and latch in written data to GCSXBLNK = 0;Cube_Delay();GSLAT = 1;// Set the shift register to turn on the current layerint i;for (i = 0; i < CUBE_LAYER_COUNT; i++) {Cube_Delay();SFT_D = (i == CUBE_LAYER_COUNT - cube_data_ptr->current_layer - 1) ? 1 : 0;Cube_Delay();SFT_K = 1;Cube_Delay();SFT_K = 0;}Cube_Delay();SFT_S = 1;Cube_Delay();SFT_S = 0;Cube_Delay();// Enable LED outputXBLNK = 1;Cube_Delay();GSLAT = 0;cube_data_ptr->current_layer = (cube_data_ptr->current_layer == CUBE_LAYER_COUNT-1)? 0 : cube_data_ptr->current_layer + 1;}void Cube_Write_DCS(char BC) {// Ensure that the brightness isnt set too highif (BC > CUBE_MAX_BRIGHTNESS)BC = CUBE_MAX_BRIGHTNESS;XBLNK = 0;int i,j;// Write configuration data to the DC/BC/FC/UD registersunsigned char DCS[GCS_LAYER_SIZE] = {0};for (i = 0; i < 8; i++) {int offset = i * GCS_REG_SIZE;for (j = 0; j < 21; j++) {DCS[offset + j] = 0xFF; // Dot correction}// Warning: do not set BC > 0x6FDCS[offset + 21] = BC; // Global red brightnessDCS[offset + 22] = BC; // Global green brightnessDCS[offset + 23] = BC; // Global blue brightness// DC low range, auto repeat, no timing reset, 8 bit counter modeDCS[offset + 24] = 0x68; // 0110 1000}GSLAT = 1;SPI1_Write(DCS, GCS_LAYER_SIZE, &Cube_DCS_Write_Callback);Delay_MS(10); // Delay until the entire DCS write is finished}void Cube_Clear(void) {int i,j;for (i = 0; i < CUBE_LAYER_COUNT; i++)for (j = 0; j < GCS_LAYER_SIZE; j++)cube_data_ptr->GCS[i][j] = 0x00;}void Cube_Set_All(int R, int G, int B) {// Set all pixels in the cube to the given colorR &= 0x0FFF;G &= 0x0FFF;B &= 0x0FFF;int i,j,k;for (i = 0; i < CUBE_LAYER_COUNT; i++) {for (j = 0; j < CUBE_ROW_COUNT; j++) {int j_var = j * GCS_REG_SIZE;for (k = 0; k < 4; k++) {int k_var = j_var + (k * 9);cube_data_ptr->GCS[i][k_var+0] = R & 0xFF;;cube_data_ptr->GCS[i][k_var+1] = (G << 4) | (R >> 8);cube_data_ptr->GCS[i][k_var+2] = G >> 4;cube_data_ptr->GCS[i][k_var+3] = B & 0xFF;cube_data_ptr->GCS[i][k_var+4] = (R << 4) | (B >> 8);cube_data_ptr->GCS[i][k_var+5] = R >> 4;cube_data_ptr->GCS[i][k_var+6] = G & 0xFF;cube_data_ptr->GCS[i][k_var+7] = (B << 4) | (G >> 8);cube_data_ptr->GCS[i][k_var+8] = B >> 4;}}}}void Cube_Set_Layer(int layer, int R, int G, int B) {// Set all pixels in the specified layer to the given colorR &= 0x0FFF;G &= 0x0FFF;B &= 0x0FFF;int i,j;for (i = 0; i < CUBE_ROW_COUNT; i++) {int i_var = i * GCS_REG_SIZE;for (j = 0; j < 4; j++) {int j_var = i_var + (j * 9);cube_data_ptr->GCS[layer][j_var+0] = R & 0xFF;;cube_data_ptr->GCS[layer][j_var+1] = (G << 4) | (R >> 8);cube_data_ptr->GCS[layer][j_var+2] = G >> 4;cube_data_ptr->GCS[layer][j_var+3] = B & 0xFF;cube_data_ptr->GCS[layer][j_var+4] = (R << 4) | (B >> 8);cube_data_ptr->GCS[layer][j_var+5] = R >> 4;cube_data_ptr->GCS[layer][j_var+6] = G & 0xFF;cube_data_ptr->GCS[layer][j_var+7] = (B << 4) | (G >> 8);cube_data_ptr->GCS[layer][j_var+8] = B >> 4;}}}void Cube_Set_Pixel(int layer, int row, int column, int R, int G, int B) {// Set the specified pixel to the given colorR &= 0x0FFF;G &= 0x0FFF;B &= 0x0FFF;int var = row * GCS_REG_SIZE + (column / 2 * 9);switch (column % 2) {case 0:cube_data_ptr->GCS[layer][var+0] = R & 0xFF;cube_data_ptr->GCS[layer][var+1] = (G << 4) | (R >> 8);cube_data_ptr->GCS[layer][var+2] = G >> 4;cube_data_ptr->GCS[layer][var+3] = B & 0xFF;cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0xF0) | (B >> 8);break;case 1:cube_data_ptr->GCS[layer][var+4] = (cube_data_ptr->GCS[layer][var+4] & 0x0F) | (R << 4);cube_data_ptr->GCS[layer][var+5] = R >> 4;cube_data_ptr->GCS[layer][var+6] = G & 0xFF;cube_data_ptr->GCS[layer][var+7] = (B << 4) | (G >> 8);cube_data_ptr->GCS[layer][var+8] = B >> 4;break;}}