Subversion Repositories Code-Repo

Compare Revisions

Problem with comparison.

Ignore whitespace Rev HEAD → Rev 274

/PIC Stuff/Cerebot_32MX7_LED_Cube/ANIMATIONS.c
0,0 → 1,553
#include "defines.h"
#include "ANIMATIONS.h"
#include "CUBE.h"
 
void Animation_Solid_Colors(uint16_t delay_ms) {
Cube_Set_All(RED);
Delay_MS(delay_ms);
Cube_Set_All(GREEN);
Delay_MS(delay_ms);
Cube_Set_All(BLUE);
Delay_MS(delay_ms);
}
 
void Animation_Layer_Alternate(uint16_t delay_ms) {
uint8_t i;
for (i = 0; i < CUBE_LAYER_COUNT; i++) {
if (i % 3 == 0)
Cube_Set_Layer(i,RED);
else if (i % 3 == 1)
Cube_Set_Layer(i,GREEN);
else
Cube_Set_Layer(i,BLUE);
}
Delay_MS(delay_ms);
for (i = 0; i < CUBE_LAYER_COUNT; i++) {
if (i % 3 == 0)
Cube_Set_Layer(i,GREEN);
else if (i % 3 == 1)
Cube_Set_Layer(i,BLUE);
else
Cube_Set_Layer(i,RED);
}
Delay_MS(delay_ms);
for (i = 0; i < CUBE_LAYER_COUNT; i++) {
if (i % 3 == 0)
Cube_Set_Layer(i,BLUE);
else if (i % 3 == 1)
Cube_Set_Layer(i,RED);
else
Cube_Set_Layer(i,GREEN);
}
Delay_MS(delay_ms);
}
 
void Animation_Pixel_Alternate(uint16_t delay_ms) {
uint8_t i,j,k;
for (i = 0; i < CUBE_LAYER_COUNT; i++) {
Cube_Clear();
for (j = 0; j < CUBE_ROW_COUNT; j++) {
for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
int32_t var = (j * 8) + k;
if (var % 3 == 0)
Cube_Set_Pixel(i,j,k,RED);
else if (var % 3 == 1)
Cube_Set_Pixel(i,j,k,GREEN);
else
Cube_Set_Pixel(i,j,k,BLUE);
}
}
Delay_MS(delay_ms);
Cube_Clear();
for (j = 0; j < CUBE_ROW_COUNT; j++) {
for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
int32_t var = (j * 8) + k;
if (var % 3 == 0)
Cube_Set_Pixel(i,j,k,GREEN);
else if (var % 3 == 1)
Cube_Set_Pixel(i,j,k,BLUE);
else
Cube_Set_Pixel(i,j,k,RED);
}
}
Delay_MS(delay_ms);
Cube_Clear();
for (j = 0; j < CUBE_ROW_COUNT; j++) {
for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
int32_t var = (j * 8) + k;
if (var % 3 == 0)
Cube_Set_Pixel(i,j,k,BLUE);
else if (var % 3 == 1)
Cube_Set_Pixel(i,j,k,RED);
else
Cube_Set_Pixel(i,j,k,GREEN);
}
}
Delay_MS(delay_ms);
}
}
 
void Animation_Full_Color_Sweep(uint16_t delay_us) {
int16_t i;
for (i = 0; i < 0x0FF; i+=2) {
Cube_Set_All(i,0,0);
Delay_US(delay_us);
}
for (i = 0; i < 0x0FF; i+=2) {
Cube_Set_All(0x0FF,i,0);
Delay_US(delay_us);
}
for (i = 0x0FF; i >= 0; i-=2) {
Cube_Set_All(i,0x0FF,0);
Delay_US(delay_us);
}
for (i = 0; i < 0x0FF; i+=2) {
Cube_Set_All(0,0x0FF,i);
Delay_US(delay_us);
}
for (i = 0; i < 0x0FF; i+=2) {
Cube_Set_All(i,0x0FF,0x0FF);
Delay_US(delay_us);
}
for (i = 0x0FF; i >= 0; i-=2) {
Cube_Set_All(0x0FF,i,0x0FF);
Delay_US(delay_us);
}
for (i = 0x0FF; i >= 0; i-=2) {
Cube_Set_All(i,0,0x0FF);
Delay_US(delay_us);
}
for (i = 0x0FF; i >= 0; i-=2) {
Cube_Set_All(0,0,i);
Delay_US(delay_us);
}
}
 
void Animation_Row_Column_Sweep(uint16_t delay_ms) {
uint8_t i,j,k,a;
for (i = 0; i < 3; i++) {
for (j = 0; j < CUBE_ROW_COUNT; j++) {
Cube_Clear();
for (k = 0; k < CUBE_COLUMN_COUNT; k++)
if (i % 3 == 0)
for (a = 0; a < CUBE_LAYER_COUNT; a++)
Cube_Set_Pixel(a,j,k,RED);
else if (i % 3 == 1)
for (a = 0; a < CUBE_LAYER_COUNT; a++)
Cube_Set_Pixel(a,j,k,GREEN);
else
for (a = 0; a < CUBE_LAYER_COUNT; a++)
Cube_Set_Pixel(a,j,k,BLUE);
Delay_MS(delay_ms);
}
for (j = 0; j < CUBE_ROW_COUNT; j++) {
Cube_Clear();
for (k = 0; k < CUBE_COLUMN_COUNT; k++)
if (i % 3 == 0)
for (a = 0; a < CUBE_LAYER_COUNT; a++)
Cube_Set_Pixel(a,k,j,RED);
else if (i % 3 == 1)
for (a = 0; a < CUBE_LAYER_COUNT; a++)
Cube_Set_Pixel(a,k,j,GREEN);
else
for (a = 0; a < CUBE_LAYER_COUNT; a++)
Cube_Set_Pixel(a,k,j,BLUE);
Delay_MS(delay_ms);
}
for (j = CUBE_LAYER_COUNT; j != 0; j--) {
Cube_Clear();
if (i % 3 == 0) {
for (k = 0; k < CUBE_LAYER_COUNT; k++)
if (k == j)
Cube_Set_Layer(k,RED);
} else if (i % 3 == 1) {
for (k = 0; k < CUBE_LAYER_COUNT; k++)
if (k == j)
Cube_Set_Layer(k,GREEN);
} else {
for (k = 0; k < CUBE_LAYER_COUNT; k++)
if (k == j)
Cube_Set_Layer(k,BLUE);
}
Delay_MS(delay_ms);
}
}
}
 
void Animation_Pixel_Sweep(uint16_t delay_ms) {
uint8_t i,j,k,a;
for (a = 0; a < 3; a++) {
for (i = 0; i < CUBE_LAYER_COUNT; i++) {
for (j = 0; j < CUBE_ROW_COUNT; j++) {
for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
Cube_Clear();
if (a % 3 == 0) {
Cube_Set_Pixel(i,j,k,RED);
} else if (a % 3 == 1) {
Cube_Set_Pixel(i,j,k,GREEN);
} else {
Cube_Set_Pixel(i,j,k,BLUE);
}
Delay_MS(delay_ms);
}
}
}
}
}
 
void Animation_Pseudo_Random_Colors(uint16_t delay_ms) {
uint8_t i,j,k;
for (i = 0; i < CUBE_LAYER_COUNT; i++) {
for (j = 0; j < CUBE_ROW_COUNT; j++) {
for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
uint32_t a = rand();
if (a % 5 == 0)
Cube_Set_Pixel(i,j,k,RED);
else if (a % 5 == 1)
Cube_Set_Pixel(i,j,k,GREEN);
else if (a % 5 == 2)
Cube_Set_Pixel(i,j,k,BLUE);
else if (a % 5 == 3)
Cube_Set_Pixel(i,j,k,PURPLE);
else if (a % 5 == 4)
Cube_Set_Pixel(i,j,k,YELLOW);
else
Cube_Set_Pixel(i,j,k,ORANGE);
}
}
}
Delay_MS(delay_ms);
}
 
void Animation_Random_Colors(uint16_t delay_ms) {
uint8_t i,j,k;
for (i = 0; i < CUBE_LAYER_COUNT; i++) {
for (j = 0; j < CUBE_ROW_COUNT; j++) {
for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
Cube_Set_Pixel(i,j,k,rand()&0x0FF,rand()&0x0FF,rand()&0x0FF);
}
}
}
Delay_MS(delay_ms);
}
 
void Animation_Cube_In_Cube(uint16_t delay_ms) {
uint8_t x;
for (x = 0; x < 6; x++) {
Cube_Clear();
if (x == 0)
Cube_Set_Shell(0, RED);
else if (x == 1 || x == 5)
Cube_Set_Shell(1, YELLOW);
else if (x == 2 || x == 4)
Cube_Set_Shell(2, GREEN);
else if (x == 3)
Cube_Set_Shell(3, BLUE);
Delay_MS(delay_ms);
}
}
 
void Animation_Cube_In_Out(uint16_t delay_ms, uint16_t r, uint16_t g, uint16_t b) {
uint8_t x,i,j,k;
for (x = 0; x < 7; x++) {
Cube_Clear();
switch (x % 7) {
case 0:
Cube_Set_Shell(3, r, g, b);
break;
case 1:
Cube_Set_Shell(2, r, g, b);
break;
case 2:
Cube_Set_Shell(1, r, g, b);
break;
case 3:
Cube_Set_Shell(0, r, g, b);
break;
case 4:
Cube_Set_Shell(1, r, g, b);
break;
case 5:
Cube_Set_Shell(2, r, g, b);
break;
case 6:
Cube_Set_Shell(3, r, g, b);
break;
}
 
// for (i = 0; i < CUBE_LAYER_COUNT; i++) {
// if ((x == 0 || x == 6)&&(i == 0 || i == 7)) {
// Cube_Set_Layer(i,r,g,b);
// } else if ((x == 1 || x == 5)&&(i == 1 || i == 6)) {
// for (j = 1; j < CUBE_ROW_COUNT-1; j++)
// for (k = 1; k < CUBE_COLUMN_COUNT-1; k++)
// Cube_Set_Pixel(i,j,k,r,g,b);
// } else if ((x == 2 || x == 4)&&(i == 2 || i == 5)) {
// for (j = 2; j < CUBE_ROW_COUNT-2; j++)
// for (k = 2; k < CUBE_COLUMN_COUNT-2; k++)
// Cube_Set_Pixel(i,j,k,r,g,b);
// } else if ((x == 3)&&(i == 3 || i == 4)) {
// for (j = 3; j < CUBE_ROW_COUNT-3; j++)
// for (k = 3; k < CUBE_COLUMN_COUNT-3; k++)
// Cube_Set_Pixel(i,j,k,r,g,b);
// }
//
// if ((x == 0 || x == 6)&&(i > 0 && i < 8)) {
// for (j = 0; j < 8; j++) {
// Cube_Set_Pixel(i,j,0,r,g,b);
// Cube_Set_Pixel(i,j,7,r,g,b);
// Cube_Set_Pixel(i,0,j,r,g,b);
// Cube_Set_Pixel(i,7,j,r,g,b);
// }
// }
// if ((x == 1 || x == 5)&&(i > 1 && i < 7)) {
// for (j = 1; j < 7; j++) {
// Cube_Set_Pixel(i,j,1,r,g,b);
// Cube_Set_Pixel(i,j,6,r,g,b);
// Cube_Set_Pixel(i,1,j,r,g,b);
// Cube_Set_Pixel(i,6,j,r,g,b);
// }
// }
// if ((x == 2 || x == 4)&&(i > 2 && i < 6)) {
// for (j = 2; j < 6; j++) {
// Cube_Set_Pixel(i,j,2,r,g,b);
// Cube_Set_Pixel(i,j,5,r,g,b);
// Cube_Set_Pixel(i,2,j,r,g,b);
// Cube_Set_Pixel(i,5,j,r,g,b);
// }
// }
// }
Delay_MS(delay_ms);
}
}
 
void Animation_Double_Rotation(uint16_t delay_ms) {
Cube_Clear();
uint8_t x,y,z;
 
for (y = 0; y < CUBE_LAYER_COUNT; y++) {
Cube_Set_Pixel(y,0,0,RED);
Cube_Set_Pixel(y,1,1,ORANGE);
Cube_Set_Pixel(y,2,2,YELLOW);
Cube_Set_Pixel(y,3,3,GREEN);
Cube_Set_Pixel(y,4,4,TEAL);
Cube_Set_Pixel(y,5,5,BLUE);
Cube_Set_Pixel(y,6,6,PURPLE);
Cube_Set_Pixel(y,7,7,WHITE);
}
for (x = 0; x < 28; x++) {
Delay_MS(delay_ms);
Cube_Rotate(0);
}
}
 
// for (z = 0; z < 3; z++) {
// switch (z % 3) {
// case 0:
// for (y = 0; y < CUBE_LAYER_COUNT; y++) {
// Cube_Set_Pixel(y,0,0,RED);
// Cube_Set_Pixel(y,1,1,RED);
// Cube_Set_Pixel(y,2,2,RED);
// Cube_Set_Pixel(y,3,3,RED);
// Cube_Set_Pixel(y,4,4,RED);
// Cube_Set_Pixel(y,5,5,RED);
// Cube_Set_Pixel(y,6,6,RED);
// Cube_Set_Pixel(y,7,7,RED);
// }
// break;
// case 1:
// for (y = 0; y < CUBE_LAYER_COUNT; y++) {
// Cube_Set_Pixel(y,0,0,GREEN);
// Cube_Set_Pixel(y,1,1,GREEN);
// Cube_Set_Pixel(y,2,2,GREEN);
// Cube_Set_Pixel(y,3,3,GREEN);
// Cube_Set_Pixel(y,4,4,GREEN);
// Cube_Set_Pixel(y,5,5,GREEN);
// Cube_Set_Pixel(y,6,6,GREEN);
// Cube_Set_Pixel(y,7,7,GREEN);
// }
// break;
// case 2:
// for (y = 0; y < CUBE_LAYER_COUNT; y++) {
// Cube_Set_Pixel(y,0,0,BLUE);
// Cube_Set_Pixel(y,1,1,BLUE);
// Cube_Set_Pixel(y,2,2,BLUE);
// Cube_Set_Pixel(y,3,3,BLUE);
// Cube_Set_Pixel(y,4,4,BLUE);
// Cube_Set_Pixel(y,5,5,BLUE);
// Cube_Set_Pixel(y,6,6,BLUE);
// Cube_Set_Pixel(y,7,7,BLUE);
// }
// break;
// }
//
// for (x = 0; x < 28; x++) {
// Delay_MS(delay_ms);
// Cube_Rotate(0);
// }
// }
//}
 
void Animation_Wave1(uint16_t delay_ms) {
uint8_t i, j;
static uint8_t data[8];
uint32_t r;
for (i = 0; i < 16; i++) {
for (j = 0; j < 8; j++) {
r = rand();
if (r % 3 == 0) {
// Increase
data[j] = (data[j] == CUBE_LAYER_COUNT - 1) ? data[j] : data[j] + 1;
} else if (r % 3 == 1) {
// Decrease
data[j] = (data[j] == 0) ? data[j] : data[j] - 1;
} else {
// No change
data[j] = data[j];
}
}
Cube_Shift_Waterfall(data);
Delay_MS(delay_ms);
}
}
 
void Animation_Wave2(uint16_t delay_ms) {
uint8_t i, j;
static uint8_t data[8];
uint32_t r;
 
for (i = 0; i < 16; i++) {
for (j = 0; j < 8; j++) {
r = rand();
if (r % 3 == 0) {
// Increase
data[j] = (data[j] == CUBE_LAYER_COUNT - 1) ? data[j] : data[j] + 1;
} else if (r % 3 == 1) {
// Decrease
data[j] = (data[j] == 0) ? data[j] : data[j] - 1;
} else {
// No change
data[j] = data[j];
}
}
Cube_Shift_Waterfall2(data);
Delay_MS(delay_ms);
}
}
 
void Animation_Sphere(uint16_t delay_ms) {
Cube_Clear();
Cube_Set_Sphere(0, RED);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(1, ORANGE);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(2, YELLOW);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(3, GREEN);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(4, BLUE);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(5, PURPLE);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(6, RED);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(7, ORANGE);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(8, YELLOW);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(7, ORANGE);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(6, RED);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(5, PURPLE);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(4, BLUE);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(3, GREEN);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(2, YELLOW);
Delay_MS(delay_ms);
Cube_Clear();
Cube_Set_Sphere(1, ORANGE);
Delay_MS(delay_ms);
Cube_Clear();
}
 
void Animation_Sawtooth(uint16_t delay_ms) {
uint8_t i;
uint8_t dir = 1;
uint8_t layer_dir = 1;
uint8_t layer_min = 0;
uint8_t layer_max = CUBE_LAYER_COUNT;
uint8_t layer = layer_min;
 
for (i = 0; i < 48; i++) {
Cube_Set_Row(7, 0x00, 0x00, 0x00);
Cube_Set_Pixel(layer, 7, 0, RED);
Cube_Set_Pixel(layer, 7, 1, ORANGE);
Cube_Set_Pixel(layer, 7, 2, YELLOW);
Cube_Set_Pixel(layer, 7, 3, GREEN);
Cube_Set_Pixel(layer, 7, 4, TEAL);
Cube_Set_Pixel(layer, 7, 5, BLUE);
Cube_Set_Pixel(layer, 7, 6, PURPLE);
Cube_Set_Pixel(layer, 7, 7, WHITE);
if (dir)
layer++;
else
layer--;
 
// Decrease the maximum layer
if (layer == layer_min) {
dir = 1;
if (layer_dir)
layer_max--;
else
layer_max++;
}
 
// Increase the minimum layer
if (layer == layer_max - 1) {
dir = 0;
if (layer_dir)
layer_min++;
else
layer_min--;
}
 
// Change the layer gap to expansion
if (layer_max - layer_min < 3) {
if (layer_dir)
layer_dir = 0;
else
layer_dir = 1;
}
 
// Change the layer gap to reduction
if (layer == 0) {
if (layer_dir)
layer_dir = 0;
else
layer_dir = 1;
}
Delay_MS(delay_ms);
Cube_Shift_Row(0);
}
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/ANIMATIONS.h
0,0 → 1,23
#ifndef ANIMATIONS_H
#define ANIMATIONS_H
 
void Animation_Solid_Colors(uint16_t delay_ms);
void Animation_Layer_Alternate(uint16_t delay_ms);
void Animation_Pixel_Alternate(uint16_t delay_ms);
void Animation_Full_Color_Sweep(uint16_t delay_us);
void Animation_Row_Column_Sweep(uint16_t delay_ms);
void Animation_Pixel_Sweep(uint16_t delay_ms);
void Animation_Pseudo_Random_Colors(uint16_t delay_ms);
void Animation_Random_Colors(uint16_t delay_ms);
void Animation_Cube_In_Cube(uint16_t delay_ms);
void Animation_Cube_In_Out(uint16_t delay_ms, uint16_t r, uint16_t g, uint16_t b);
void Animation_Double_Rotation(uint16_t delay_ms);
void Animation_Wave1(uint16_t delay_ms);
void Animation_Wave2(uint16_t delay_ms);
void Animation_Sphere(uint16_t delay_ms);
void Animation_Sawtooth(uint16_t delay_ms);
 
void Animation_Cube_In_Out(uint16_t delay_ms, uint16_t r, uint16_t g, uint16_t b);
 
#endif /* ANIMATIONS_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/CONTROLLERS.c
0,0 → 1,180
#include "defines.h"
#include "CONTROLLERS.h"
#include "I2C1.h"
 
static CONTROLLER_DATA *ctrl_data_p;
 
void Controller_Init(CONTROLLER_DATA *data) {
ctrl_data_p = data;
 
// Variable initialization
int i;
for (i = 0; i < CONTROLLER_MAX_COUNT; i++) {
ctrl_data_p->connected_controllers[i] = 0x0;
ctrl_data_p->led_status[i][0] = 0x0;
ctrl_data_p->led_status[i][1] = 0x0;
ctrl_data_p->btn_prev[i] = 0x0;
ctrl_data_p->btn_last[i] = 0x0;
}
 
ctrl_data_p->connected_count = 0x0;
 
// Poll to see which controllers are connected
Controller_Poll_Connected();
}
 
void Controller_Poll_Connected(void) {
uint8_t buffer[2] = {CONTROLLER_CMD_RESET};
uint8_t result, length, i;
uint8_t address = CONTROLLER_PREFIX_ADDRESS + CONTROLLER_START_ADDRESS;
 
// Attempt to contact each controller to see if its connected
for (i = 0; i < CONTROLLER_MAX_COUNT; i++) {
// I2C1_Master_Send(address + i, buffer, 1);
// do {
// result = I2C1_Get_Status();
// } while (!result);
// if (result == I2C1_SEND_OK) {
// // If a controller is connected, save its address
// ctrl_data_p->connected_controllers[ctrl_data_p->connected_count]
// = address + i;
// ctrl_data_p->connected_count++;
// }
I2C1_Master_Restart(address + i, CONTROLLER_CMD_READ, 1);
do {
result = I2C1_Get_Status();
} while (!result);
if (result == I2C1_RECV_OK) {
length = I2C1_Read_Buffer(buffer);
// If a controller is connected, save its address
ctrl_data_p->connected_controllers[ctrl_data_p->connected_count]
= address + i;
ctrl_data_p->connected_count++;
}
}
}
 
void Controller_Update(void) {
/*
uint8_t buffer[2];
uint8_t result, length;
uint8_t ctrl_1_btn = 0, ctrl_2_btn = 0;
 
// Read button values from controllers
I2C1_Master_Restart(CONTROLLER_1_ADDRESS, CONTROLLER_READ, 1);
do {
result = I2C1_Get_Status();
} while (!result);
if (result == I2C1_RECV_OK) {
// Indicate that controller 1 is connected
LED1_LAT = 1;
ctrl_data_p->ctrl_1_connected = 1;
length = I2C1_Read_Buffer(buffer);
buffer[0] = ~buffer[0];
// Button change detected
if (ctrl_data_p->ctrl_1_buttons_prev != buffer[0]) {
// Check if a button has been pressed since startup
if (!ctrl_data_p->ctrl_1_active) {
ctrl_data_p->ctrl_1_active = 1;
}
// Figure out which button has changed
ctrl_1_btn = ctrl_data_p->ctrl_1_buttons_prev ^ buffer[0];
// Save the button if it went from unpressed -> pressed
ctrl_1_btn &= buffer[0];
}
ctrl_data_p->ctrl_1_buttons_prev = buffer[0];
} else {
LED1_LAT = 0;
ctrl_data_p->ctrl_1_connected = 0;
ctrl_data_p->ctrl_1_active = 0;
}
 
I2C1_Master_Restart(CONTROLLER_2_ADDRESS, CONTROLLER_READ, 1);
do {
result = I2C1_Get_Status();
} while (!result);
if (result == I2C1_RECV_OK) {
// Indicate that controller 2 is connected
LED2_LAT = 1;
ctrl_data_p->ctrl_2_connected = 1;
length = I2C1_Read_Buffer(buffer);
buffer[0] = ~buffer[0];
// Button change detected
if (ctrl_data_p->ctrl_2_buttons_prev != buffer[0]) {
// Check if a button has been pressed since startup
if (!ctrl_data_p->ctrl_2_active) {
ctrl_data_p->ctrl_2_active = 1;
}
// Figure out which button has changed
ctrl_2_btn = ctrl_data_p->ctrl_2_buttons_prev ^ buffer[0];
// Save the button if it went from unpressed -> pressed
ctrl_2_btn &= buffer[0];
}
ctrl_data_p->ctrl_2_buttons_prev = buffer[0];
} else {
LED2_LAT = 0;
ctrl_data_p->ctrl_2_connected = 0;
ctrl_data_p->ctrl_2_active = 0;
}
 
// Write LED values to controllers
if (ctrl_data_p->ctrl_1_connected) {
buffer[0] = CONTROLLER_WRITE;
buffer[1] = ctrl_data_p->ctrl_1_leds;
I2C1_Master_Send(CONTROLLER_1_ADDRESS, buffer, 2);
do {
result = I2C1_Get_Status();
} while (!result);
}
 
if (ctrl_data_p->ctrl_2_connected) {
buffer[0] = CONTROLLER_WRITE;
buffer[1] = ctrl_data_p->ctrl_2_leds;
I2C1_Master_Send(CONTROLLER_2_ADDRESS, buffer, 2);
do {
result = I2C1_Get_Status();
} while (!result);
}
 
// If board is in an idle state and a controller is connected, switch modes
if (Get_Board_State() == BOARD_MODE_IDLE) {
// If both controllers are active, go into game TRON mode
if (ctrl_data_p->ctrl_1_active && ctrl_data_p->ctrl_2_active) {
Reset_Board(BOARD_MODE_TRON);
}
// Otherwise if only one controller is active, go into game SNAKE mode
if (ctrl_data_p->ctrl_1_active || ctrl_data_p->ctrl_2_active) {
Reset_Board(BOARD_MODE_SNAKE);
}
}
if (Get_Board_State() == BOARD_MODE_SNAKE) {
// If both controllers are active, go into game TRON mode
if (ctrl_data_p->ctrl_1_active && ctrl_data_p->ctrl_2_active) {
Reset_Board(BOARD_MODE_TRON);
}
}
 
// Call the callback function if any buttons have changed
if (ctrl_data_p->btn_change_callback != NULL) {
if (ctrl_1_btn || ctrl_2_btn) {
(*ctrl_data_p->btn_change_callback)(ctrl_1_btn, ctrl_2_btn);
}
}
*/
}
 
void Controller_Set_Leds(uint8_t controller, uint16_t value) {
// ctrl_data_p->ctrl_1_leds = ctrl_1;
// ctrl_data_p->ctrl_2_leds = ctrl_2;
}
 
uint8_t Controller_Query(uint8_t controller) {
// // Returns the active status of attached controllers
// if (ctrl_data_p->ctrl_1_active && ctrl_data_p->ctrl_2_active)
// return 0x3;
// else if (ctrl_data_p->ctrl_1_active)
// return 0x1;
// else if (ctrl_data_p->ctrl_2_active)
// return 0x2;
// return 0;
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/CONTROLLERS.h
0,0 → 1,33
#ifndef CONTROLLERS_H
#define CONTROLLERS_H
 
#define CONTROLLER_CMD_READ 0xA
#define CONTROLLER_CMD_WRITE 0xB
#define CONTROLLER_CMD_RESET 0xC
 
#define CONTROLLER_BTN_DEFAULT 0xC0
#define CONTROLLER_LED_DEFAULT 0x00
 
#define CONTROLLER_PREFIX_ADDRESS 0xA0
#define CONTROLLER_START_ADDRESS 0x01
#define CONTROLLER_END_ADDRESS 0x08
 
#define CONTROLLER_MAX_COUNT 8
 
typedef struct {
uint8_t connected_controllers[CONTROLLER_MAX_COUNT];
uint8_t led_status[CONTROLLER_MAX_COUNT][2];
uint8_t btn_prev[CONTROLLER_MAX_COUNT];
uint8_t btn_last[CONTROLLER_MAX_COUNT];
 
uint8_t connected_count;
} CONTROLLER_DATA;
 
void Controller_Init(CONTROLLER_DATA *data);
void Controller_Poll_Connected(void);
void Controller_Update(void);
void Controller_Set_Leds(uint8_t controller, uint16_t value);
uint8_t Controller_Query(uint8_t controller);
 
#endif /* CONTROLLERS_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/defines.h
0,0 → 1,55
// PIC32MX795F512L
 
#ifndef DEFINES_H
#define DEFINES_H
 
#include <xc.h>
#include <plib.h>
#include <stdint.h>
 
// Uncomment ONE of the following:
#define CEREBOT_32MX7
// #define CEREBOT_MX7CK
 
#define CPU_CLOCK_HZ 80000000UL
#define PERIPHERAL_CLOCK_HZ 80000000UL
#define CPU_CT_HZ (CPU_CLOCK_HZ/2UL)
#define MS_TO_CT_TICKS (CPU_CLOCK_HZ/2000UL)
#define US_TO_CT_TICKS (CPU_CLOCK_HZ/2000000UL)
 
#define ADDRESS_EEPROM 0x50
#define ADDRESS_CONTROLLER_1 0x24
#define ADDRESS_CONTROLLER_2 0x25
 
// LED1 = G12, LED2 = G13, LED3 = G14, LED4 = G15 (active high)
#define LED1_TRIS TRISGbits.TRISG12
#define LED1_LAT LATGbits.LATG12
#define LED2_TRIS TRISGbits.TRISG13
#define LED2_LAT LATGbits.LATG13
#define LED3_TRIS TRISGbits.TRISG14
#define LED3_LAT LATGbits.LATG14
#define LED4_TRIS TRISGbits.TRISG15
#define LED4_LAT LATGbits.LATG15
 
// Reset conditions
#define RESET_POR 0x01 // Power on reset
#define RESET_BOR 0x02 // Brown out reset
#define RESET_SWR 0x03 // Software reset
#define RESET_WDT 0x04 // Watchdog timer reset
#define RESET_PIN 0x05 // MCLR pin reset
#define RESET_CFG 0x06 // Config mismatch reset
 
// Board 'modes' (idle/games/etc)
#define BOARD_MODE_IDLE 0x1
#define BOARD_MODE_SNAKE 0x2
#define BOARD_MODE_TRON 0x3
#define BOARD_MODE_ETHERNET 0x4
 
void Delay_MS(uint32_t delay_ms);
void Delay_US(uint32_t delay_us);
uint8_t Get_Reset_Condition(void);
uint8_t Get_Board_State(void);
void Reset_Board(uint8_t next_state);
void Idle_Animation_Sequence(void);
 
#endif /* DEFINES_H */
/PIC Stuff/Cerebot_32MX7_LED_Cube/main.c
0,0 → 1,412
// <editor-fold defaultstate="collapsed" desc="Configuration Bits">
/* ------------------------------------------------------------ */
/* PIC32 Configuration Settings */
/* ------------------------------------------------------------ */
/* Oscillator Settings */
#pragma config FNOSC = PRIPLL // Oscillator Selection Bits
#pragma config POSCMOD = EC // Primary Oscillator Configuration
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider
#pragma config FPLLMUL = MUL_20 // PLL Multiplier
#pragma config FPLLODIV = DIV_1 // PLL Output Divider
#pragma config FPBDIV = DIV_1 // Peripheral Clock Divisor (timers/UART/SPI/I2C)
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable
/* Clock Control Settings */
#pragma config IESO = OFF // Internal/External Clock Switch Over
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin
/* USB Settings */
#pragma config UPLLEN = ON // USB PLL Enable
#pragma config UPLLIDIV = DIV_2 // USB PLL Input Divider
#pragma config FVBUSONIO = OFF // USB VBUS ON Selection
#pragma config FUSBIDIO = OFF // USB USID Selection
/* Other Peripheral Device Settings */
#pragma config FWDTEN = OFF // Watchdog Timer Enable
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1048.576s)
#pragma config FSRSSEL = PRIORITY_7 // SRS Interrupt Priority
#pragma config FCANIO = OFF // CAN I/O Pin Select (default/alternate)
#pragma config FETHIO = ON // Ethernet I/O Pin Select (default/alternate)
#pragma config FMIIEN = OFF // Ethernet MII/RMII select (OFF=RMII)
/* Code Protection Settings */
#pragma config CP = OFF // Code Protect
#pragma config BWP = OFF // Boot Flash Write Protect
#pragma config PWP = OFF // Program Flash Write Protect
/* Debug Settings */
#pragma config ICESEL = ICS_PGx1 // ICE/ICD Comm Channel Select (on-board debugger)
/* ------------------------------------------------------------ */
// </editor-fold>
 
#include "defines.h"
#include "UART1.h"
#include "SPI1.h"
#include "SPI4.h"
#include "I2C1.h"
#include "ETHERNET.h"
#include "TIMER4.h"
#include "TIMER5.h"
#include "CUBE.h"
#include "BTN.h"
#include "ANIMATIONS.h"
#include "CONTROLLERS.h"
#include "SNAKE.h"
#include "TRON.h"
 
void BTN1_Interrupt(void);
void BTN2_Interrupt(void);
void BTN3_Interrupt(void);
 
void Delay_MS(uint32_t delay_ms) {
// Delays the CPU for the given amount of time.
// Note: Watch out for integer overflow! (max delay_ms = 107374) ??
uint32_t delay = delay_ms * MS_TO_CT_TICKS;
uint32_t startTime = ReadCoreTimer();
while ((uint32_t)(ReadCoreTimer() - startTime) < delay) {};
}
 
void Delay_US(uint32_t delay_us) {
// Delays the CPU for the given amount of time.
// Note: Watch out for integer overflow!
uint32_t delay = delay_us * US_TO_CT_TICKS;
uint32_t startTime = ReadCoreTimer();
while ((uint32_t)(ReadCoreTimer() - startTime) < delay) {};
}
 
uint8_t Get_Reset_Condition(void) {
uint8_t ret = 0;
if (RCONbits.POR && RCONbits.BOR)
ret = RESET_POR;
else if (RCONbits.BOR)
ret = RESET_BOR;
else if (RCONbits.EXTR)
ret = RESET_PIN;
else if (RCONbits.SWR)
ret = RESET_SWR;
else if (RCONbits.CMR)
ret = RESET_CFG;
else if (RCONbits.WDTO)
ret = RESET_WDT;
// Clear the RCON register
RCON = 0x0;
return ret;
}
 
// Initialize a persistent operational state machine
volatile static uint8_t op_state __attribute__((persistent));
 
uint8_t Get_Board_State(void) {
return op_state;
}
 
void Reset_Board(uint8_t next_state) {
op_state = next_state;
// Executes a software reset
INTDisableInterrupts();
SYSKEY = 0x00000000; // Write invalid key to force lock
SYSKEY = 0xAA996655; // Write key1 to SYSKEY
SYSKEY = 0x556699AA; // Write key2 to SYSKEY
/* OSCCON is now unlocked */
// Set SWRST bit to arm reset
RSWRSTSET = 1;
// Read RSWRST register to trigger reset
uint32_t dummy;
dummy = RSWRST;
// Prevent any unwanted code execution until reset occurs
while(1);
}
 
void main() {
// WARNING!! THIS BOARD WILL RESET EVERY 1048.576s DUE TO THE WDT!!
 
/* -------------------- BEGIN INITIALIZATION --------------------- */
// Configure the target for maximum performance at 80 MHz.
// Note: This overrides the peripheral clock to 80Mhz regardless of config
SYSTEMConfigPerformance(CPU_CLOCK_HZ);
 
// Configure the interrupts for multiple vectors
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
 
// Set all analog I/O pins to digital
AD1PCFGSET = 0xFFFF;
 
// Enable the watchdog timer with windowed mode disabled
// WDT prescaler set to 1048576 (1048.576s) (see config bits)
WDTCON = 0x00008000;
 
// Configure onboard LEDs
LED1_TRIS = 0;
LED2_TRIS = 0;
LED3_TRIS = 0;
LED4_TRIS = 0;
LED1_LAT = 0;
LED2_LAT = 0;
LED3_LAT = 0;
LED4_LAT = 0;
 
// Determine what to do at this point. We either choose to idle (on POR)
// or go into a mode specified prior to the software reset event
uint8_t last_reset = Get_Reset_Condition();
if (last_reset == RESET_POR || last_reset == RESET_BOR ||
last_reset == RESET_PIN || last_reset == RESET_WDT ||
last_reset == RESET_CFG) {
op_state = BOARD_MODE_IDLE;
}
 
// Initialize the SPI1 module
SPI1_DATA spi_1_data;
SPI1_Init(&spi_1_data, NULL);
 
// Initialize the SPI4 module
SPI4_DATA spi_4_data;
SPI4_Init(&spi_4_data);
 
// Initialize the I2C1 module
I2C1_DATA i2c_1_data;
I2C1_Init(&i2c_1_data, I2C1_400KHZ, 0x20);
 
// // Initialize the UART1 module
// UART1_DATA uart_data;
// UART1_Init(&uart_data, &Cube_Data_In);
 
// Initializs the PWM2 output to 20MHz
PWM2_Init();
 
// Initialize the cube variables
CUBE_DATA cube_data;
Cube_Init(&cube_data, 0x40);
 
// Start the cube update layer interrupt
// 2083 = 60Hz, 500 = 250Hz, 250 = 500Hz
TIMER5_DATA timer_5_data;
TIMER5_Init(&timer_5_data, &Cube_Timer_Interrupt, 500);
 
// Start the controller polling and overlay rotation interrupt
TIMER4_DATA timer_4_data;
TIMER4_Init(&timer_4_data, NULL, NULL, 0);
 
// Process button inputs
BTN_DATA btn_data;
BTN_Init(&btn_data, &BTN1_Interrupt, &BTN2_Interrupt, NULL);
 
// Initialize controllers
CONTROLLER_DATA ctrl_data;
Controller_Init(&ctrl_data);
 
// Initialize the Ethernet module
if (op_state == BOARD_MODE_ETHERNET) {
LED1_LAT = 1;
ETH_DATA eth_data;
ETH_Init(&eth_data, NULL, &Cube_Ethernet_Frame_In);
}
SNAKE_DATA snake_data;
TRON_DATA tron_data;
 
PWM2_Start();
TIMER5_Start();
/* -------------------- END OF INITIALIZATION -------------------- */
/* ------------------------ BEGIN DISPLAY ------------------------ */
 
// Figure out what to do at this point (depending on current state)
switch (op_state) {
case BOARD_MODE_IDLE:
Idle_Animation_Sequence();
break;
case BOARD_MODE_SNAKE:;
Controller_Init(&ctrl_data);
TIMER4_Init(NULL, &Controller_Update, NULL, 0);
TIMER4_Start();
Snake_Init(&snake_data);
Snake_Main();
break;
case BOARD_MODE_TRON:
Controller_Init(&ctrl_data);
TIMER4_Init(NULL, &Controller_Update, NULL, 0);
TIMER4_Start();
Tron_Init(&tron_data);
Tron_Main();
break;
case BOARD_MODE_ETHERNET:
TIMER4_Stop();
LED2_LAT = 1;
while(1);
break;
}
 
}
 
void Idle_Animation_Sequence(void) {
 
// Cube_Set_All(RED);
// Delay_MS(2000);
// Cube_Set_All(GREEN);
// Delay_MS(2000);
// Cube_Set_All(BLUE);
// Delay_MS(2000);
// Animation_Pseudo_Random_Colors(200);
// Animation_Pseudo_Random_Colors(200);
// Animation_Pseudo_Random_Colors(200);
// Animation_Pseudo_Random_Colors(200);
// Animation_Pseudo_Random_Colors(200);
// Animation_Pseudo_Random_Colors(200);
 
// Start the scrolling text
TIMER4_Stop();
TIMER4_Init(NULL, NULL, &Cube_Text_Interrupt, 100);
// TIMER4_Start();
 
// int8_t start_text[] = "Cube Initialized\r\n";
// UART1_Write(start_text, 18);
 
// Set the overlay text
uint8_t text_string[] = "Welcome to the CCM Lab ";
Cube_Text_Init(text_string, 27, 0xFF, 0xFF, 0xFF);
// TIMER4_Start();
 
// Loop through some preset animations
while(1) {
 
Animation_Sawtooth(100);
Animation_Sawtooth(100);
Animation_Sawtooth(100);
Animation_Sphere(100);
Animation_Sphere(100);
Animation_Sphere(100);
Animation_Sphere(100);
Animation_Wave1(100);
Animation_Wave1(100);
Animation_Wave1(100);
Animation_Wave1(100);
Animation_Wave2(100);
Animation_Wave2(100);
Animation_Wave2(100);
Animation_Wave2(100);
// Animation_Solid_Colors(300);
// Animation_Layer_Alternate(300);
// Animation_Pixel_Alternate(200);
// Animation_Full_Color_Sweep(1000);
Animation_Row_Column_Sweep(40);
Animation_Row_Column_Sweep(40);
Animation_Cube_In_Cube(300);
Animation_Cube_In_Cube(300);
Animation_Cube_In_Cube(300);
Animation_Double_Rotation(30);
Animation_Double_Rotation(30);
Animation_Double_Rotation(30);
Animation_Double_Rotation(30);
Animation_Pseudo_Random_Colors(300);
Animation_Pseudo_Random_Colors(300);
Animation_Pseudo_Random_Colors(300);
Animation_Pseudo_Random_Colors(300);
Animation_Pseudo_Random_Colors(300);
Animation_Pseudo_Random_Colors(300);
Animation_Pseudo_Random_Colors(300);
Animation_Pseudo_Random_Colors(300);
Animation_Pseudo_Random_Colors(300);
Animation_Pseudo_Random_Colors(300);
// Animation_Random_Colors(300);
 
// ClearWDT(); // Clear the WDT if we dont want the board to reset
}
}
 
// Function call on button 1 press to change cube operation
void BTN1_Interrupt(void) {
switch (op_state) {
case BOARD_MODE_IDLE:
Reset_Board(BOARD_MODE_SNAKE);
break;
case BOARD_MODE_SNAKE:
Reset_Board(BOARD_MODE_TRON);
break;
case BOARD_MODE_TRON:
Reset_Board(BOARD_MODE_ETHERNET);
break;
case BOARD_MODE_ETHERNET:
Reset_Board(BOARD_MODE_IDLE);
break;
}
 
// Code to change refresh rate on button press
// static uint8_t state;
// state = (state == 4) ? 0 : state + 1;
// TIMER5_Stop();
// switch (state) {
// case 0:
// TIMER5_Init(NULL, &Cube_Timer_Interrupt, 500); // 250Hz
// break;
// case 1:
// TIMER5_Init(NULL, &Cube_Timer_Interrupt, 2083); // 60Hz
// break;
// case 2:
// TIMER5_Init(NULL, &Cube_Timer_Interrupt, 4166); // 30Hz
// break;
// case 3:
// TIMER5_Init(NULL, &Cube_Timer_Interrupt, 12498); // 10Hz
// break;
// case 4:
// TIMER5_Init(NULL, &Cube_Timer_Interrupt, 24996); // 5Hz
// break;
// }
// TIMER5_Start();
}
 
// Function call on button 2 press to change brightness
void BTN2_Interrupt(void) {
static uint8_t state = 6;
state = (state == 6) ? 0 : state + 1;
TIMER5_Stop();
Delay_MS(1); // Need to wait for all SPI writes to complete
uint8_t BC;
switch (state) {
case 0:
BC = 0x01;
break;
case 1:
BC = 0x08;
break;
case 2:
BC = 0x10;
break;
case 3:
BC = 0x20;
break;
case 4:
BC = 0x40;
break;
case 5:
BC = 0x80;
break;
case 6:
BC = 0xFF;
break;
}
Cube_Write_DCS(BC);
TIMER5_Start();
}
 
//// Function call on button 3 press to change text scroll speed
//void BTN3_Interrupt(void) {
// static uint8_t state;
// state = (state == 4) ? 0 : state + 1;
// TIMER4_Stop();
// switch (state) {
// case 0:
// TIMER4_Init(NULL, &Cube_Text_Interrupt, 209712);
// break;
// case 1:
// TIMER4_Init(NULL, &Cube_Text_Interrupt, 180000);
// break;
// case 2:
// TIMER4_Init(NULL, &Cube_Text_Interrupt, 150000);
// break;
// case 3:
// TIMER4_Init(NULL, &Cube_Text_Interrupt, 120000);
// break;
// case 4:
// TIMER4_Init(NULL, &Cube_Text_Interrupt, 90000);
// break;
// }
// TIMER4_Start();
//}
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-genesis.properties
0,0 → 1,8
#
#Thu Mar 13 23:02:03 EDT 2014
default.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=83f4565fa27ad9b8015f63d69ef74f66
default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\xc32\\v1.31\\bin
com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=1f98a0eed69cb2a45c12981fa9470927
default.languagetoolchain.version=1.31
host.platform=windows
conf.ids=default
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/configurations.xml
0,0 → 1,214
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="62">
<logicalFolder name="root" displayName="root" projectFiles="true">
<logicalFolder name="HeaderFiles"
displayName="Header Files"
projectFiles="true">
<itemPath>defines.h</itemPath>
<itemPath>SPI1.h</itemPath>
<itemPath>TIMER5.h</itemPath>
<itemPath>CUBE.h</itemPath>
<itemPath>BTN.h</itemPath>
<itemPath>PWM2.h</itemPath>
<itemPath>TIMER4.h</itemPath>
<itemPath>glcdfont.h</itemPath>
<itemPath>UART1.h</itemPath>
<itemPath>SPI4.h</itemPath>
<itemPath>ANIMATIONS.h</itemPath>
<itemPath>I2C1.h</itemPath>
<itemPath>CONTROLLERS.h</itemPath>
<itemPath>SNAKE.h</itemPath>
<itemPath>TRON.h</itemPath>
<itemPath>ETHERNET.h</itemPath>
</logicalFolder>
<logicalFolder name="LinkerScript"
displayName="Linker Files"
projectFiles="true">
</logicalFolder>
<logicalFolder name="SourceFiles"
displayName="Source Files"
projectFiles="true">
<itemPath>main.c</itemPath>
<itemPath>SPI1.c</itemPath>
<itemPath>TIMER5.c</itemPath>
<itemPath>CUBE.c</itemPath>
<itemPath>PWM2.c</itemPath>
<itemPath>BTN.c</itemPath>
<itemPath>TIMER4.c</itemPath>
<itemPath>UART1.c</itemPath>
<itemPath>SPI4.c</itemPath>
<itemPath>ANIMATIONS.c</itemPath>
<itemPath>I2C1.c</itemPath>
<itemPath>CONTROLLERS.c</itemPath>
<itemPath>SNAKE.c</itemPath>
<itemPath>TRON.c</itemPath>
<itemPath>ETHERNET.c</itemPath>
</logicalFolder>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
projectFiles="false">
<itemPath>Makefile</itemPath>
<itemPath>README.txt</itemPath>
</logicalFolder>
</logicalFolder>
<projectmakefile>Makefile</projectmakefile>
<confs>
<conf name="default" type="2">
<toolsSet>
<developmentServer>localhost</developmentServer>
<targetDevice>PIC32MX795F512L</targetDevice>
<targetHeader></targetHeader>
<targetPluginBoard></targetPluginBoard>
<platformTool>PK3OBPlatformTool</platformTool>
<languageToolchain>XC32</languageToolchain>
<languageToolchainVersion>1.31</languageToolchainVersion>
<platform>3</platform>
</toolsSet>
<compileType>
<linkerTool>
<linkerLibItems>
</linkerLibItems>
</linkerTool>
<loading>
<useAlternateLoadableFile>false</useAlternateLoadableFile>
<alternateLoadableFile></alternateLoadableFile>
</loading>
</compileType>
<makeCustomizationType>
<makeCustomizationPreStepEnabled>false</makeCustomizationPreStepEnabled>
<makeCustomizationPreStep></makeCustomizationPreStep>
<makeCustomizationPostStepEnabled>false</makeCustomizationPostStepEnabled>
<makeCustomizationPostStep></makeCustomizationPostStep>
<makeCustomizationPutChecksumInUserID>false</makeCustomizationPutChecksumInUserID>
<makeCustomizationEnableLongLines>false</makeCustomizationEnableLongLines>
<makeCustomizationNormalizeHexFile>false</makeCustomizationNormalizeHexFile>
</makeCustomizationType>
<C32>
<property key="additional-warnings" value="false"/>
<property key="enable-app-io" value="false"/>
<property key="enable-omit-frame-pointer" value="false"/>
<property key="enable-symbols" value="true"/>
<property key="enable-unroll-loops" value="true"/>
<property key="exclude-floating-point" value="false"/>
<property key="extra-include-directories" value=""/>
<property key="generate-16-bit-code" value="false"/>
<property key="generate-micro-compressed-code" value="false"/>
<property key="isolate-each-function" value="false"/>
<property key="make-warnings-into-errors" value="false"/>
<property key="optimization-level" value="-O1"/>
<property key="place-data-into-section" value="false"/>
<property key="post-instruction-scheduling" value="default"/>
<property key="pre-instruction-scheduling" value="default"/>
<property key="preprocessor-macros" value=""/>
<property key="strict-ansi" value="false"/>
<property key="support-ansi" value="false"/>
<property key="use-cci" value="false"/>
<property key="use-iar" value="false"/>
<property key="use-indirect-calls" value="false"/>
</C32>
<C32-AS>
<property key="assembler-symbols" value=""/>
<property key="enable-symbols" value="true"/>
<property key="exclude-floating-point-library" value="false"/>
<property key="expand-macros" value="false"/>
<property key="extra-include-directories-for-assembler" value=""/>
<property key="extra-include-directories-for-preprocessor" value=""/>
<property key="false-conditionals" value="false"/>
<property key="keep-locals" value="false"/>
<property key="list-assembly" value="false"/>
<property key="list-source" value="false"/>
<property key="list-symbols" value="false"/>
<property key="oXC32asm-list-to-file" value="false"/>
<property key="omit-debug-dirs" value="false"/>
<property key="omit-forms" value="false"/>
<property key="preprocessor-macros" value=""/>
<property key="warning-level" value=""/>
</C32-AS>
<C32-LD>
<property key="additional-options-use-response-files" value="false"/>
<property key="enable-check-sections" value="false"/>
<property key="exclude-floating-point-library" value="false"/>
<property key="exclude-standard-libraries" value="false"/>
<property key="extra-lib-directories" value=""/>
<property key="fill-flash-options-addr" value=""/>
<property key="fill-flash-options-const" value=""/>
<property key="fill-flash-options-how" value="0"/>
<property key="fill-flash-options-inc-const" value="1"/>
<property key="fill-flash-options-increment" value=""/>
<property key="fill-flash-options-seq" value=""/>
<property key="fill-flash-options-what" value="0"/>
<property key="generate-16-bit-code" value="false"/>
<property key="generate-cross-reference-file" value="false"/>
<property key="generate-micro-compressed-code" value="false"/>
<property key="heap-size" value=""/>
<property key="input-libraries" value=""/>
<property key="linker-symbols" value=""/>
<property key="map-file" value=""/>
<property key="no-startup-files" value="false"/>
<property key="oXC32ld-extra-opts" value=""/>
<property key="optimization-level" value=""/>
<property key="preprocessor-macros" value=""/>
<property key="remove-unused-sections" value="false"/>
<property key="report-memory-usage" value="true"/>
<property key="stack-size" value=""/>
<property key="symbol-stripping" value=""/>
<property key="trace-symbols" value=""/>
<property key="warn-section-align" value="false"/>
</C32-LD>
<C32CPP>
<property key="additional-warnings" value="false"/>
<property key="check-new" value="false"/>
<property key="eh-specs" value="true"/>
<property key="enable-app-io" value="false"/>
<property key="enable-omit-frame-pointer" value="false"/>
<property key="enable-symbols" value="true"/>
<property key="enable-unroll-loops" value="true"/>
<property key="exceptions" value="true"/>
<property key="exclude-floating-point" value="false"/>
<property key="extra-include-directories" value=""/>
<property key="generate-16-bit-code" value="false"/>
<property key="generate-micro-compressed-code" value="false"/>
<property key="isolate-each-function" value="false"/>
<property key="make-warnings-into-errors" value="false"/>
<property key="optimization-level" value="-O1"/>
<property key="place-data-into-section" value="false"/>
<property key="post-instruction-scheduling" value="default"/>
<property key="pre-instruction-scheduling" value="default"/>
<property key="preprocessor-macros" value=""/>
<property key="rtti" value="true"/>
<property key="strict-ansi" value="false"/>
<property key="use-cci" value="false"/>
<property key="use-iar" value="false"/>
<property key="use-indirect-calls" value="false"/>
</C32CPP>
<C32Global>
<property key="legacy-libc" value="false"/>
<property key="save-temps" value="false"/>
<property key="wpo-lto" value="false"/>
</C32Global>
<PK3OBPlatformTool>
<property key="AutoSelectMemRanges" value="auto"/>
<property key="SecureSegment.SegmentProgramming" value="FullChipProgramming"/>
<property key="ToolFirmwareFilePath"
value="Press to browse for a specific firmware version"/>
<property key="ToolFirmwareOption.UseLatestFirmware" value="true"/>
<property key="memories.bootflash" value="false"/>
<property key="memories.configurationmemory" value="false"/>
<property key="memories.eeprom" value="false"/>
<property key="memories.id" value="false"/>
<property key="memories.programmemory" value="true"/>
<property key="memories.programmemory.end" value="0x1d07ffff"/>
<property key="memories.programmemory.start" value="0x1d000000"/>
<property key="poweroptions.powerenable" value="false"/>
<property key="programoptions.eraseb4program" value="true"/>
<property key="programoptions.preserveeeprom" value="false"/>
<property key="programoptions.preserveprogramrange" value="false"/>
<property key="programoptions.preserveprogramrange.end" value="0x1d0001ff"/>
<property key="programoptions.preserveprogramrange.start" value="0x1d000000"/>
<property key="programoptions.usehighvoltageonmclr" value="false"/>
<property key="programoptions.uselvpprogramming" value="false"/>
<property key="voltagevalue" value="3.25"/>
</PK3OBPlatformTool>
</conf>
</confs>
</configurationDescriptor>
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/private/configurations.xml
0,0 → 1,25
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="62">
<projectmakefile>Makefile</projectmakefile>
<defaultConf>0</defaultConf>
<confs>
<conf name="default" type="2">
<platformToolSN>:=MPLABComm-USB-Microchip:=&lt;vid>04D8:=&lt;pid>8108:=&lt;rev>0002:=&lt;man>Digilent:=&lt;prod>Cerebot 32MX7:=&lt;sn>D370400:=&lt;drv>x:=&lt;xpt>h:=end</platformToolSN>
<languageToolchainDir>C:\Program Files (x86)\Microchip\xc32\v1.31\bin</languageToolchainDir>
<mdbdebugger version="1">
<placeholder1>place holder 1</placeholder1>
<placeholder2>place holder 2</placeholder2>
</mdbdebugger>
<runprofile version="6">
<args></args>
<rundir></rundir>
<buildfirst>true</buildfirst>
<console-type>0</console-type>
<terminal-type>0</terminal-type>
<remove-instrumentation>0</remove-instrumentation>
<environment>
</environment>
</runprofile>
</conf>
</confs>
</configurationDescriptor>
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/private/private.xml
0,0 → 1,3
<?xml version="1.0" encoding="UTF-8"?><project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
</project-private>
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/private/private.properties
--- nbproject/project.xml (nonexistent)
+++ nbproject/project.xml (revision 274)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>com.microchip.mplab.nbide.embedded.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>Cerebot_32MX7_LED_Cube</name>
+ <creation-uuid>a23479a1-6afc-4362-a20c-e5ddcf3c7815</creation-uuid>
+ <make-project-type>0</make-project-type>
+ <c-extensions>c</c-extensions>
+ <cpp-extensions/>
+ <header-extensions>h</header-extensions>
+ <sourceEncoding>ISO-8859-1</sourceEncoding>
+ <asminc-extensions/>
+ <make-dep-projects/>
+ </data>
+ </configuration>
+</project>
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-default.mk
0,0 → 1,316
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a -pre and a -post target defined where you can add customized code.
#
# This makefile implements configuration specific macros and targets.
 
 
# Include project Makefile
ifeq "${IGNORE_LOCAL}" "TRUE"
# do not include local makefile. User is passing all local related variables already
else
include Makefile
# Include makefile containing local settings
ifeq "$(wildcard nbproject/Makefile-local-default.mk)" "nbproject/Makefile-local-default.mk"
include nbproject/Makefile-local-default.mk
endif
endif
 
# Environment
MKDIR=gnumkdir -p
RM=rm -f
MV=mv
CP=cp
 
# Macros
CND_CONF=default
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
IMAGE_TYPE=debug
OUTPUT_SUFFIX=elf
DEBUGGABLE_SUFFIX=elf
FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
else
IMAGE_TYPE=production
OUTPUT_SUFFIX=hex
DEBUGGABLE_SUFFIX=elf
FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
endif
 
# Object Directory
OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE}
 
# Distribution Directory
DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE}
 
# Source Files Quoted if spaced
SOURCEFILES_QUOTED_IF_SPACED=main.c SPI1.c TIMER5.c CUBE.c PWM2.c BTN.c TIMER4.c UART1.c SPI4.c ANIMATIONS.c I2C1.c CONTROLLERS.c SNAKE.c TRON.c ETHERNET.c
 
# Object Files Quoted if spaced
OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/main.o ${OBJECTDIR}/SPI1.o ${OBJECTDIR}/TIMER5.o ${OBJECTDIR}/CUBE.o ${OBJECTDIR}/PWM2.o ${OBJECTDIR}/BTN.o ${OBJECTDIR}/TIMER4.o ${OBJECTDIR}/UART1.o ${OBJECTDIR}/SPI4.o ${OBJECTDIR}/ANIMATIONS.o ${OBJECTDIR}/I2C1.o ${OBJECTDIR}/CONTROLLERS.o ${OBJECTDIR}/SNAKE.o ${OBJECTDIR}/TRON.o ${OBJECTDIR}/ETHERNET.o
POSSIBLE_DEPFILES=${OBJECTDIR}/main.o.d ${OBJECTDIR}/SPI1.o.d ${OBJECTDIR}/TIMER5.o.d ${OBJECTDIR}/CUBE.o.d ${OBJECTDIR}/PWM2.o.d ${OBJECTDIR}/BTN.o.d ${OBJECTDIR}/TIMER4.o.d ${OBJECTDIR}/UART1.o.d ${OBJECTDIR}/SPI4.o.d ${OBJECTDIR}/ANIMATIONS.o.d ${OBJECTDIR}/I2C1.o.d ${OBJECTDIR}/CONTROLLERS.o.d ${OBJECTDIR}/SNAKE.o.d ${OBJECTDIR}/TRON.o.d ${OBJECTDIR}/ETHERNET.o.d
 
# Object Files
OBJECTFILES=${OBJECTDIR}/main.o ${OBJECTDIR}/SPI1.o ${OBJECTDIR}/TIMER5.o ${OBJECTDIR}/CUBE.o ${OBJECTDIR}/PWM2.o ${OBJECTDIR}/BTN.o ${OBJECTDIR}/TIMER4.o ${OBJECTDIR}/UART1.o ${OBJECTDIR}/SPI4.o ${OBJECTDIR}/ANIMATIONS.o ${OBJECTDIR}/I2C1.o ${OBJECTDIR}/CONTROLLERS.o ${OBJECTDIR}/SNAKE.o ${OBJECTDIR}/TRON.o ${OBJECTDIR}/ETHERNET.o
 
# Source Files
SOURCEFILES=main.c SPI1.c TIMER5.c CUBE.c PWM2.c BTN.c TIMER4.c UART1.c SPI4.c ANIMATIONS.c I2C1.c CONTROLLERS.c SNAKE.c TRON.c ETHERNET.c
 
 
CFLAGS=
ASFLAGS=
LDLIBSOPTIONS=
 
############# Tool locations ##########################################
# If you copy a project from one host to another, the path where the #
# compiler is installed may be different. #
# If you open this project with MPLAB X in the new host, this #
# makefile will be regenerated and the paths will be corrected. #
#######################################################################
# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build
FIXDEPS=fixDeps
 
.build-conf: ${BUILD_SUBPROJECTS}
${MAKE} ${MAKE_OPTIONS} -f nbproject/Makefile-default.mk dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
 
MP_PROCESSOR_OPTION=32MX795F512L
MP_LINKER_FILE_OPTION=
# ------------------------------------------------------------------------------------
# Rules for buildStep: assemble
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
else
endif
 
# ------------------------------------------------------------------------------------
# Rules for buildStep: assembleWithPreprocess
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
else
endif
 
# ------------------------------------------------------------------------------------
# Rules for buildStep: compile
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
${OBJECTDIR}/main.o: main.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/main.o.d
@${RM} ${OBJECTDIR}/main.o
@${FIXDEPS} "${OBJECTDIR}/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/main.o.d" -o ${OBJECTDIR}/main.o main.c
${OBJECTDIR}/SPI1.o: SPI1.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/SPI1.o.d
@${RM} ${OBJECTDIR}/SPI1.o
@${FIXDEPS} "${OBJECTDIR}/SPI1.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/SPI1.o.d" -o ${OBJECTDIR}/SPI1.o SPI1.c
${OBJECTDIR}/TIMER5.o: TIMER5.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/TIMER5.o.d
@${RM} ${OBJECTDIR}/TIMER5.o
@${FIXDEPS} "${OBJECTDIR}/TIMER5.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/TIMER5.o.d" -o ${OBJECTDIR}/TIMER5.o TIMER5.c
${OBJECTDIR}/CUBE.o: CUBE.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/CUBE.o.d
@${RM} ${OBJECTDIR}/CUBE.o
@${FIXDEPS} "${OBJECTDIR}/CUBE.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/CUBE.o.d" -o ${OBJECTDIR}/CUBE.o CUBE.c
${OBJECTDIR}/PWM2.o: PWM2.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/PWM2.o.d
@${RM} ${OBJECTDIR}/PWM2.o
@${FIXDEPS} "${OBJECTDIR}/PWM2.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/PWM2.o.d" -o ${OBJECTDIR}/PWM2.o PWM2.c
${OBJECTDIR}/BTN.o: BTN.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/BTN.o.d
@${RM} ${OBJECTDIR}/BTN.o
@${FIXDEPS} "${OBJECTDIR}/BTN.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/BTN.o.d" -o ${OBJECTDIR}/BTN.o BTN.c
${OBJECTDIR}/TIMER4.o: TIMER4.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/TIMER4.o.d
@${RM} ${OBJECTDIR}/TIMER4.o
@${FIXDEPS} "${OBJECTDIR}/TIMER4.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/TIMER4.o.d" -o ${OBJECTDIR}/TIMER4.o TIMER4.c
${OBJECTDIR}/UART1.o: UART1.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/UART1.o.d
@${RM} ${OBJECTDIR}/UART1.o
@${FIXDEPS} "${OBJECTDIR}/UART1.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/UART1.o.d" -o ${OBJECTDIR}/UART1.o UART1.c
${OBJECTDIR}/SPI4.o: SPI4.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/SPI4.o.d
@${RM} ${OBJECTDIR}/SPI4.o
@${FIXDEPS} "${OBJECTDIR}/SPI4.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/SPI4.o.d" -o ${OBJECTDIR}/SPI4.o SPI4.c
${OBJECTDIR}/ANIMATIONS.o: ANIMATIONS.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/ANIMATIONS.o.d
@${RM} ${OBJECTDIR}/ANIMATIONS.o
@${FIXDEPS} "${OBJECTDIR}/ANIMATIONS.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/ANIMATIONS.o.d" -o ${OBJECTDIR}/ANIMATIONS.o ANIMATIONS.c
${OBJECTDIR}/I2C1.o: I2C1.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/I2C1.o.d
@${RM} ${OBJECTDIR}/I2C1.o
@${FIXDEPS} "${OBJECTDIR}/I2C1.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/I2C1.o.d" -o ${OBJECTDIR}/I2C1.o I2C1.c
${OBJECTDIR}/CONTROLLERS.o: CONTROLLERS.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/CONTROLLERS.o.d
@${RM} ${OBJECTDIR}/CONTROLLERS.o
@${FIXDEPS} "${OBJECTDIR}/CONTROLLERS.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/CONTROLLERS.o.d" -o ${OBJECTDIR}/CONTROLLERS.o CONTROLLERS.c
${OBJECTDIR}/SNAKE.o: SNAKE.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/SNAKE.o.d
@${RM} ${OBJECTDIR}/SNAKE.o
@${FIXDEPS} "${OBJECTDIR}/SNAKE.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/SNAKE.o.d" -o ${OBJECTDIR}/SNAKE.o SNAKE.c
${OBJECTDIR}/TRON.o: TRON.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/TRON.o.d
@${RM} ${OBJECTDIR}/TRON.o
@${FIXDEPS} "${OBJECTDIR}/TRON.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/TRON.o.d" -o ${OBJECTDIR}/TRON.o TRON.c
${OBJECTDIR}/ETHERNET.o: ETHERNET.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/ETHERNET.o.d
@${RM} ${OBJECTDIR}/ETHERNET.o
@${FIXDEPS} "${OBJECTDIR}/ETHERNET.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/ETHERNET.o.d" -o ${OBJECTDIR}/ETHERNET.o ETHERNET.c
else
${OBJECTDIR}/main.o: main.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/main.o.d
@${RM} ${OBJECTDIR}/main.o
@${FIXDEPS} "${OBJECTDIR}/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/main.o.d" -o ${OBJECTDIR}/main.o main.c
${OBJECTDIR}/SPI1.o: SPI1.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/SPI1.o.d
@${RM} ${OBJECTDIR}/SPI1.o
@${FIXDEPS} "${OBJECTDIR}/SPI1.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/SPI1.o.d" -o ${OBJECTDIR}/SPI1.o SPI1.c
${OBJECTDIR}/TIMER5.o: TIMER5.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/TIMER5.o.d
@${RM} ${OBJECTDIR}/TIMER5.o
@${FIXDEPS} "${OBJECTDIR}/TIMER5.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/TIMER5.o.d" -o ${OBJECTDIR}/TIMER5.o TIMER5.c
${OBJECTDIR}/CUBE.o: CUBE.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/CUBE.o.d
@${RM} ${OBJECTDIR}/CUBE.o
@${FIXDEPS} "${OBJECTDIR}/CUBE.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/CUBE.o.d" -o ${OBJECTDIR}/CUBE.o CUBE.c
${OBJECTDIR}/PWM2.o: PWM2.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/PWM2.o.d
@${RM} ${OBJECTDIR}/PWM2.o
@${FIXDEPS} "${OBJECTDIR}/PWM2.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/PWM2.o.d" -o ${OBJECTDIR}/PWM2.o PWM2.c
${OBJECTDIR}/BTN.o: BTN.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/BTN.o.d
@${RM} ${OBJECTDIR}/BTN.o
@${FIXDEPS} "${OBJECTDIR}/BTN.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/BTN.o.d" -o ${OBJECTDIR}/BTN.o BTN.c
${OBJECTDIR}/TIMER4.o: TIMER4.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/TIMER4.o.d
@${RM} ${OBJECTDIR}/TIMER4.o
@${FIXDEPS} "${OBJECTDIR}/TIMER4.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/TIMER4.o.d" -o ${OBJECTDIR}/TIMER4.o TIMER4.c
${OBJECTDIR}/UART1.o: UART1.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/UART1.o.d
@${RM} ${OBJECTDIR}/UART1.o
@${FIXDEPS} "${OBJECTDIR}/UART1.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/UART1.o.d" -o ${OBJECTDIR}/UART1.o UART1.c
${OBJECTDIR}/SPI4.o: SPI4.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/SPI4.o.d
@${RM} ${OBJECTDIR}/SPI4.o
@${FIXDEPS} "${OBJECTDIR}/SPI4.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/SPI4.o.d" -o ${OBJECTDIR}/SPI4.o SPI4.c
${OBJECTDIR}/ANIMATIONS.o: ANIMATIONS.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/ANIMATIONS.o.d
@${RM} ${OBJECTDIR}/ANIMATIONS.o
@${FIXDEPS} "${OBJECTDIR}/ANIMATIONS.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/ANIMATIONS.o.d" -o ${OBJECTDIR}/ANIMATIONS.o ANIMATIONS.c
${OBJECTDIR}/I2C1.o: I2C1.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/I2C1.o.d
@${RM} ${OBJECTDIR}/I2C1.o
@${FIXDEPS} "${OBJECTDIR}/I2C1.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/I2C1.o.d" -o ${OBJECTDIR}/I2C1.o I2C1.c
${OBJECTDIR}/CONTROLLERS.o: CONTROLLERS.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/CONTROLLERS.o.d
@${RM} ${OBJECTDIR}/CONTROLLERS.o
@${FIXDEPS} "${OBJECTDIR}/CONTROLLERS.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/CONTROLLERS.o.d" -o ${OBJECTDIR}/CONTROLLERS.o CONTROLLERS.c
${OBJECTDIR}/SNAKE.o: SNAKE.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/SNAKE.o.d
@${RM} ${OBJECTDIR}/SNAKE.o
@${FIXDEPS} "${OBJECTDIR}/SNAKE.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/SNAKE.o.d" -o ${OBJECTDIR}/SNAKE.o SNAKE.c
${OBJECTDIR}/TRON.o: TRON.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/TRON.o.d
@${RM} ${OBJECTDIR}/TRON.o
@${FIXDEPS} "${OBJECTDIR}/TRON.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/TRON.o.d" -o ${OBJECTDIR}/TRON.o TRON.c
${OBJECTDIR}/ETHERNET.o: ETHERNET.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/ETHERNET.o.d
@${RM} ${OBJECTDIR}/ETHERNET.o
@${FIXDEPS} "${OBJECTDIR}/ETHERNET.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/ETHERNET.o.d" -o ${OBJECTDIR}/ETHERNET.o ETHERNET.c
endif
 
# ------------------------------------------------------------------------------------
# Rules for buildStep: compileCPP
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
else
endif
 
# ------------------------------------------------------------------------------------
# Rules for buildStep: link
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE}
${MP_CC} $(MP_EXTRA_LD_PRE) -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -mreserve=data@0x0:0x1FC -mreserve=boot@0x1FC02000:0x1FC02FEF -mreserve=boot@0x1FC02000:0x1FC024FF -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,--defsym=__MPLAB_DEBUGGER_PK3=1,--report-mem
else
dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE}
${MP_CC} $(MP_EXTRA_LD_PRE) -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--report-mem
${MP_CC_DIR}\\xc32-bin2hex dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX}
endif
 
 
# Subprojects
.build-subprojects:
 
 
# Subprojects
.clean-subprojects:
 
# Clean Targets
.clean-conf: ${CLEAN_SUBPROJECTS}
${RM} -r build/default
${RM} -r dist/default
 
# Enable dependency checking
.dep.inc: .depcheck-impl
 
DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES})
ifneq (${DEPFILES},)
include ${DEPFILES}
endif
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-local-default.mk
0,0 → 1,37
#
# Generated Makefile - do not edit!
#
#
# This file contains information about the location of compilers and other tools.
# If you commmit this file into your revision control server, you will be able to
# to checkout the project and build it from the command line with make. However,
# if more than one person works on the same project, then this file might show
# conflicts since different users are bound to have compilers in different places.
# In that case you might choose to not commit this file and let MPLAB X recreate this file
# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at
# least once so the file gets created and the project can be built. Finally, you can also
# avoid using this file at all if you are only building from the command line with make.
# You can invoke make with the values of the macros:
# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ...
#
SHELL=cmd.exe
PATH_TO_IDE_BIN=C:/Program Files (x86)/Microchip/MPLABX/mplab_ide/mplab_ide/modules/../../bin/
# Adding MPLAB X bin directory to path.
PATH:=C:/Program Files (x86)/Microchip/MPLABX/mplab_ide/mplab_ide/modules/../../bin/:$(PATH)
# Path to java used to run MPLAB X when this makefile was created
MP_JAVA_PATH="C:\Program Files (x86)\Microchip\MPLABX\sys\java\jre1.7.0_25-windows-x64\java-windows/bin/"
OS_CURRENT="$(shell uname -s)"
MP_CC="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-gcc.exe"
MP_CPPC="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-g++.exe"
# MP_BC is not defined
MP_AS="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-as.exe"
MP_LD="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-ld.exe"
MP_AR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-ar.exe"
DEP_GEN=${MP_JAVA_PATH}java -jar "C:/Program Files (x86)/Microchip/MPLABX/mplab_ide/mplab_ide/modules/../../bin/extractobjectdependencies.jar"
MP_CC_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
MP_CPPC_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
# MP_BC_DIR is not defined
MP_AS_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
MP_LD_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
MP_AR_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
# MP_BC_DIR is not defined
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-impl.mk
0,0 → 1,69
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a pre- and a post- target defined where you can add customization code.
#
# This makefile implements macros and targets common to all configurations.
#
# NOCDDL
 
 
# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
# and .clean-reqprojects-conf unless SUB has the value 'no'
SUB_no=NO
SUBPROJECTS=${SUB_${SUB}}
BUILD_SUBPROJECTS_=.build-subprojects
BUILD_SUBPROJECTS_NO=
BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
CLEAN_SUBPROJECTS_=.clean-subprojects
CLEAN_SUBPROJECTS_NO=
CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
 
 
# Project Name
PROJECTNAME=Cerebot_32MX7_LED_Cube
 
# Active Configuration
DEFAULTCONF=default
CONF=${DEFAULTCONF}
 
# All Configurations
ALLCONFS=default
 
 
# build
.build-impl: .build-pre
${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf
 
 
# clean
.clean-impl: .clean-pre
${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf
 
# clobber
.clobber-impl: .clobber-pre .depcheck-impl
${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=default clean
 
 
 
# all
.all-impl: .all-pre .depcheck-impl
${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=default build
 
 
 
# dependency checking support
.depcheck-impl:
# @echo "# This code depends on make tool being used" >.dep.inc
# @if [ -n "${MAKE_VERSION}" ]; then \
# echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
# echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
# echo "include \$${DEPFILES}" >>.dep.inc; \
# echo "endif" >>.dep.inc; \
# else \
# echo ".KEEP_STATE:" >>.dep.inc; \
# echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
# fi
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-variables.mk
0,0 → 1,13
#
# Generated - do not edit!
#
# NOCDDL
#
CND_BASEDIR=`pwd`
# default configuration
CND_ARTIFACT_DIR_default=dist/default/production
CND_ARTIFACT_NAME_default=Cerebot_32MX7_LED_Cube.production.hex
CND_ARTIFACT_PATH_default=dist/default/production/Cerebot_32MX7_LED_Cube.production.hex
CND_PACKAGE_DIR_default=${CND_DISTDIR}/default/package
CND_PACKAGE_NAME_default=cerebot32mx7ledcube.tar
CND_PACKAGE_PATH_default=${CND_DISTDIR}/default/package/cerebot32mx7ledcube.tar
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Package-default.bash
0,0 → 1,73
#!/bin/bash -x
 
#
# Generated - do not edit!
#
 
# Macros
TOP=`pwd`
CND_CONF=default
CND_DISTDIR=dist
TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging
TMPDIRNAME=tmp-packaging
OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
OUTPUT_BASENAME=Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
PACKAGE_TOP_DIR=cerebot32mx7ledcube/
 
# Functions
function checkReturnCode
{
rc=$?
if [ $rc != 0 ]
then
exit $rc
fi
}
function makeDirectory
# $1 directory path
# $2 permission (optional)
{
mkdir -p "$1"
checkReturnCode
if [ "$2" != "" ]
then
chmod $2 "$1"
checkReturnCode
fi
}
function copyFileToTmpDir
# $1 from-file path
# $2 to-file path
# $3 permission
{
cp "$1" "$2"
checkReturnCode
if [ "$3" != "" ]
then
chmod $3 "$2"
checkReturnCode
fi
}
 
# Setup
cd "${TOP}"
mkdir -p ${CND_DISTDIR}/${CND_CONF}/package
rm -rf ${TMPDIR}
mkdir -p ${TMPDIR}
 
# Copy files and create directories and links
cd "${TOP}"
makeDirectory ${TMPDIR}/cerebot32mx7ledcube/bin
copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
 
 
# Generate tar file
cd "${TOP}"
rm -f ${CND_DISTDIR}/${CND_CONF}/package/cerebot32mx7ledcube.tar
cd ${TMPDIR}
tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/cerebot32mx7ledcube.tar *
checkReturnCode
 
# Cleanup
cd "${TOP}"
rm -rf ${TMPDIR}
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/project.properties
--- CUBE.c (nonexistent)
+++ CUBE.c (revision 274)
@@ -0,0 +1,1844 @@
+#include "defines.h"
+#include "CUBE.h"
+#include "SPI1.h"
+#include "glcdfont.h"
+#include "UART1.h"
+#include "ETHERNET.h"
+#include "TIMER4.h"
+
+static CUBE_DATA *cube_data_ptr;
+
+inline void Cube_Delay() {
+ // Small delay to ensure that latch speeds are < 30Mhz
+ Nop();
+ Nop();
+ Nop();
+}
+
+void Cube_Init(CUBE_DATA *data, uint8_t BC) {
+ cube_data_ptr = data;
+ cube_data_ptr->current_layer = 0;
+ cube_data_ptr->rotation_counter = 0;
+ cube_data_ptr->frame_state = IDLE;
+ cube_data_ptr->frame_escape = 0;
+
+ DCSIN = 0;
+ DCSCK = 0;
+ SFT_R = 0;
+ SFT_K = 0;
+ SFT_S = 0;
+ SFT_D = 0;
+ GSLAT = 0;
+ XBLNK = 0;
+
+ DCSIN_TRIS = 0;
+ DCSCK_TRIS = 0;
+ SFT_R_TRIS = 0;
+ SFT_K_TRIS = 0;
+ SFT_S_TRIS = 0;
+ SFT_D_TRIS = 0;
+ GSLAT_TRIS = 0;
+ XBLNK_TRIS = 0;
+
+ // Clear the shift register
+ Cube_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();
+ Cube_Overlay_Clear();
+}
+
+void Cube_Timer_Interrupt(void) {
+ // OR values in the overlay array with the display array
+ uint8_t i;
+ uint16_t j;
+ for (i = 0; i < CUBE_LAYER_COUNT; i++) {
+ for (j = 0; j < GCS_LAYER_SIZE; j++) {
+ cube_data_ptr->GCS_WRITE[i][j] = cube_data_ptr->GCS[i][j] | cube_data_ptr->GCS_OVERLAY[i][j];
+ }
+ }
+ // Write to the GCS register
+ SPI1_Write(cube_data_ptr->GCS_WRITE[cube_data_ptr->current_layer], GCS_LAYER_SIZE, &Cube_GCS_Write_Callback);
+}
+
+////////////////////////
+// Callback functions //
+////////////////////////
+
+void Cube_DCS_Write_Callback(void) {
+ // GSLAT must be >7ms after DCS write
+ Delay_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 GCS
+ XBLNK = 0;
+ Cube_Delay();
+ GSLAT = 1;
+ // Set the shift register to turn on the current layer
+ uint8_t 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 output
+ XBLNK = 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;
+}
+
+////////////////////////////
+// Cube control functions //
+////////////////////////////
+
+void Cube_Write_DCS(uint8_t BC) {
+ XBLNK = 0;
+ uint8_t i,j;
+ // Write configuration data to the DC/BC/FC/UD registers
+ uint8_t DCS[GCS_LAYER_SIZE] = {0};
+
+ for (i = 0; i < 8; i++) {
+ uint16_t offset = i * GCS_REG_SIZE;
+
+ for (j = 0; j < 21; j++) {
+ DCS[offset + j] = 0xFF; // Dot correction
+ }
+
+ // Warning: do not set BC > 0x6F ?? NEED TO VERIFY THIS !!
+ DCS[offset + 21] = BC; // Global red brightness
+ DCS[offset + 22] = BC; // Global green brightness
+ DCS[offset + 23] = BC; // Global blue brightness
+
+ // DC low range, auto repeat, no timing reset, 8 bit counter mode
+ DCS[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) {
+ uint8_t i;
+ uint16_t 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(uint16_t R, uint16_t G, uint16_t B) {
+ // Set all pixels in the cube to the given color
+ R &= 0x0FFF;
+ G &= 0x0FFF;
+ B &= 0x0FFF;
+ uint8_t i,j,k;
+ for (i = 0; i < CUBE_LAYER_COUNT; i++) {
+ for (j = 0; j < CUBE_ROW_COUNT; j++) {
+ uint16_t j_var = j * GCS_REG_SIZE;
+ for (k = 0; k < 4; k++) {
+ uint16_t 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(uint8_t layer, uint16_t R, uint16_t G, uint16_t B) {
+ // Set all pixels in the specified layer to the given color
+ R &= 0x0FFF;
+ G &= 0x0FFF;
+ B &= 0x0FFF;
+ uint8_t i,j;
+ for (i = 0; i < CUBE_ROW_COUNT; i++) {
+ uint16_t i_var = i * GCS_REG_SIZE;
+ for (j = 0; j < 4; j++) {
+ uint16_t 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_Row(uint8_t row, uint16_t R, uint16_t G, uint16_t B) {
+ // Set the specified row to the given color
+ R &= 0x0FFF;
+ G &= 0x0FFF;
+ B &= 0x0FFF;
+ uint8_t column, layer;
+ for (layer = 0; layer < CUBE_LAYER_COUNT; layer++) {
+ for (column = 0; column < CUBE_COLUMN_COUNT; column++) {
+ uint16_t 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;
+ }
+ }
+ }
+}
+
+void Cube_Set_Column(uint8_t column, uint16_t R, uint16_t G, uint16_t B) {
+ // Set the specified row to the given color
+ R &= 0x0FFF;
+ G &= 0x0FFF;
+ B &= 0x0FFF;
+ uint8_t row, layer;
+ for (layer = 0; layer < CUBE_LAYER_COUNT; layer++) {
+ for (row = 0; row < CUBE_COLUMN_COUNT; row++) {
+ uint16_t 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;
+ }
+ }
+ }
+}
+
+void Cube_Set_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t R, uint16_t G, uint16_t B) {
+ // Set the specified pixel to the given color
+ R &= 0x0FFF;
+ G &= 0x0FFF;
+ B &= 0x0FFF;
+ uint16_t 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;
+ }
+}
+
+void Cube_Get_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t* R, uint16_t* G, uint16_t* B) {
+ uint16_t var = row * GCS_REG_SIZE + (column / 2 * 9);
+ switch (column % 2) {
+ // Concatenate lower byte and upper byte of each color channel
+ case 0:
+ *R = cube_data_ptr->GCS[layer][var+0] | ((cube_data_ptr->GCS[layer][var+1] & 0x0F) << 8);
+ *G = (cube_data_ptr->GCS[layer][var+1] >> 4) | (cube_data_ptr->GCS[layer][var+2] << 4);
+ *B = cube_data_ptr->GCS[layer][var+3] | ((cube_data_ptr->GCS[layer][var+4] & 0x0F) << 8);
+ break;
+ case 1:
+ *R = (cube_data_ptr->GCS[layer][var+4] >> 4) | (cube_data_ptr->GCS[layer][var+5] << 4);
+ *G = cube_data_ptr->GCS[layer][var+6] | ((cube_data_ptr->GCS[layer][var+7] & 0x0F) << 8);
+ *B = (cube_data_ptr->GCS[layer][var+7] >> 4) | (cube_data_ptr->GCS[layer][var+8] << 4);
+ break;
+ }
+}
+
+void Cube_Move_Pixel(uint8_t layer1, uint8_t row1, uint8_t column1, uint8_t layer2, uint8_t row2, uint8_t column2) {
+ // Copies data from pixel 1 to pixel 2
+ // Note: destination pixel value is overwritten
+ uint16_t prev_R, prev_G, prev_B;
+ Cube_Get_Pixel(layer1, row1, column1, &prev_R, &prev_G, &prev_B);
+ Cube_Set_Pixel(layer2, row2, column2, prev_R, prev_G, prev_B);
+}
+
+void Cube_Set_Sphere(uint8_t layer, uint8_t R, uint8_t G, uint8_t B) {
+ // Super code inefficient (or is it?) lookup table
+ switch (layer % 9) {
+ case 0:
+ Cube_Set_Pixel(3, 3, 3, R, G, B);
+ Cube_Set_Pixel(3, 3, 4, R, G, B);
+ Cube_Set_Pixel(3, 4, 3, R, G, B);
+ Cube_Set_Pixel(3, 4, 4, R, G, B);
+ Cube_Set_Pixel(4, 3, 3, R, G, B);
+ Cube_Set_Pixel(4, 3, 4, R, G, B);
+ Cube_Set_Pixel(4, 4, 3, R, G, B);
+ Cube_Set_Pixel(4, 4, 4, R, G, B);
+ break;
+ case 1:
+ Cube_Set_Pixel(2, 3, 3, R, G, B);
+ Cube_Set_Pixel(2, 3, 4, R, G, B);
+ Cube_Set_Pixel(2, 4, 3, R, G, B);
+ Cube_Set_Pixel(2, 4, 4, R, G, B);
+
+ Cube_Set_Pixel(5, 3, 3, R, G, B);
+ Cube_Set_Pixel(5, 3, 4, R, G, B);
+ Cube_Set_Pixel(5, 4, 3, R, G, B);
+ Cube_Set_Pixel(5, 4, 4, R, G, B);
+
+ Cube_Set_Pixel(3, 2, 3, R, G, B);
+ Cube_Set_Pixel(3, 2, 4, R, G, B);
+ Cube_Set_Pixel(3, 5, 3, R, G, B);
+ Cube_Set_Pixel(3, 5, 4, R, G, B);
+ Cube_Set_Pixel(3, 3, 2, R, G, B);
+ Cube_Set_Pixel(3, 4, 2, R, G, B);
+ Cube_Set_Pixel(3, 3, 5, R, G, B);
+ Cube_Set_Pixel(3, 4, 5, R, G, B);
+
+ Cube_Set_Pixel(4, 2, 3, R, G, B);
+ Cube_Set_Pixel(4, 2, 4, R, G, B);
+ Cube_Set_Pixel(4, 5, 3, R, G, B);
+ Cube_Set_Pixel(4, 5, 4, R, G, B);
+ Cube_Set_Pixel(4, 3, 2, R, G, B);
+ Cube_Set_Pixel(4, 4, 2, R, G, B);
+ Cube_Set_Pixel(4, 3, 5, R, G, B);
+ Cube_Set_Pixel(4, 4, 5, R, G, B);
+ break;
+ case 2:
+ Cube_Set_Pixel(1, 3, 3, R, G, B);
+ Cube_Set_Pixel(1, 3, 4, R, G, B);
+ Cube_Set_Pixel(1, 4, 3, R, G, B);
+ Cube_Set_Pixel(1, 4, 4, R, G, B);
+
+ Cube_Set_Pixel(6, 3, 3, R, G, B);
+ Cube_Set_Pixel(6, 3, 4, R, G, B);
+ Cube_Set_Pixel(6, 4, 3, R, G, B);
+ Cube_Set_Pixel(6, 4, 4, R, G, B);
+
+ Cube_Set_Pixel(3, 1, 3, R, G, B);
+ Cube_Set_Pixel(3, 1, 4, R, G, B);
+ Cube_Set_Pixel(3, 6, 3, R, G, B);
+ Cube_Set_Pixel(3, 6, 4, R, G, B);
+ Cube_Set_Pixel(3, 3, 1, R, G, B);
+ Cube_Set_Pixel(3, 4, 1, R, G, B);
+ Cube_Set_Pixel(3, 3, 6, R, G, B);
+ Cube_Set_Pixel(3, 4, 6, R, G, B);
+
+ Cube_Set_Pixel(3, 2, 2, R, G, B);
+ Cube_Set_Pixel(3, 2, 5, R, G, B);
+ Cube_Set_Pixel(3, 5, 5, R, G, B);
+ Cube_Set_Pixel(3, 5, 2, R, G, B);
+
+ Cube_Set_Pixel(4, 1, 3, R, G, B);
+ Cube_Set_Pixel(4, 1, 4, R, G, B);
+ Cube_Set_Pixel(4, 6, 3, R, G, B);
+ Cube_Set_Pixel(4, 6, 4, R, G, B);
+ Cube_Set_Pixel(4, 3, 1, R, G, B);
+ Cube_Set_Pixel(4, 4, 1, R, G, B);
+ Cube_Set_Pixel(4, 3, 6, R, G, B);
+ Cube_Set_Pixel(4, 4, 6, R, G, B);
+
+ Cube_Set_Pixel(4, 2, 2, R, G, B);
+ Cube_Set_Pixel(4, 2, 5, R, G, B);
+ Cube_Set_Pixel(4, 5, 5, R, G, B);
+ Cube_Set_Pixel(4, 5, 2, R, G, B);
+
+ Cube_Set_Pixel(2, 3, 2, R, G, B);
+ Cube_Set_Pixel(2, 4, 2, R, G, B);
+ Cube_Set_Pixel(2, 3, 5, R, G, B);
+ Cube_Set_Pixel(2, 4, 5, R, G, B);
+ Cube_Set_Pixel(2, 2, 3, R, G, B);
+ Cube_Set_Pixel(2, 2, 4, R, G, B);
+ Cube_Set_Pixel(2, 5, 3, R, G, B);
+ Cube_Set_Pixel(2, 5, 4, R, G, B);
+
+ Cube_Set_Pixel(2, 2, 2, R, G, B);
+ Cube_Set_Pixel(2, 2, 5, R, G, B);
+ Cube_Set_Pixel(2, 5, 2, R, G, B);
+ Cube_Set_Pixel(2, 5, 5, R, G, B);
+
+ Cube_Set_Pixel(5, 3, 2, R, G, B);
+ Cube_Set_Pixel(5, 4, 2, R, G, B);
+ Cube_Set_Pixel(5, 3, 5, R, G, B);
+ Cube_Set_Pixel(5, 4, 5, R, G, B);
+ Cube_Set_Pixel(5, 2, 3, R, G, B);
+ Cube_Set_Pixel(5, 2, 4, R, G, B);
+ Cube_Set_Pixel(5, 5, 3, R, G, B);
+ Cube_Set_Pixel(5, 5, 4, R, G, B);
+
+ Cube_Set_Pixel(5, 2, 2, R, G, B);
+ Cube_Set_Pixel(5, 2, 5, R, G, B);
+ Cube_Set_Pixel(5, 5, 2, R, G, B);
+ Cube_Set_Pixel(5, 5, 5, R, G, B);
+ break;
+ case 3:
+ Cube_Set_Pixel(0, 3, 3, R, G, B);
+ Cube_Set_Pixel(0, 3, 4, R, G, B);
+ Cube_Set_Pixel(0, 4, 3, R, G, B);
+ Cube_Set_Pixel(0, 4, 4, R, G, B);
+ Cube_Set_Pixel(7, 3, 3, R, G, B);
+ Cube_Set_Pixel(7, 3, 4, R, G, B);
+ Cube_Set_Pixel(7, 4, 3, R, G, B);
+ Cube_Set_Pixel(7, 4, 4, R, G, B);
+
+ Cube_Set_Pixel(3, 0, 3, R, G, B);
+ Cube_Set_Pixel(3, 0, 4, R, G, B);
+ Cube_Set_Pixel(3, 7, 3, R, G, B);
+ Cube_Set_Pixel(3, 7, 4, R, G, B);
+ Cube_Set_Pixel(3, 3, 0, R, G, B);
+ Cube_Set_Pixel(3, 4, 0, R, G, B);
+ Cube_Set_Pixel(3, 3, 7, R, G, B);
+ Cube_Set_Pixel(3, 4, 7, R, G, B);
+
+ Cube_Set_Pixel(3, 2, 6, R, G, B);
+ Cube_Set_Pixel(3, 1, 5, R, G, B);
+ Cube_Set_Pixel(3, 6, 2, R, G, B);
+ Cube_Set_Pixel(3, 5, 1, R, G, B);
+ Cube_Set_Pixel(3, 1, 2, R, G, B);
+ Cube_Set_Pixel(3, 2, 1, R, G, B);
+ Cube_Set_Pixel(3, 6, 5, R, G, B);
+ Cube_Set_Pixel(3, 5, 6, R, G, B);
+
+ Cube_Set_Pixel(4, 0, 3, R, G, B);
+ Cube_Set_Pixel(4, 0, 4, R, G, B);
+ Cube_Set_Pixel(4, 7, 3, R, G, B);
+ Cube_Set_Pixel(4, 7, 4, R, G, B);
+ Cube_Set_Pixel(4, 3, 0, R, G, B);
+ Cube_Set_Pixel(4, 4, 0, R, G, B);
+ Cube_Set_Pixel(4, 3, 7, R, G, B);
+ Cube_Set_Pixel(4, 4, 7, R, G, B);
+
+ Cube_Set_Pixel(4, 2, 6, R, G, B);
+ Cube_Set_Pixel(4, 1, 5, R, G, B);
+ Cube_Set_Pixel(4, 6, 2, R, G, B);
+ Cube_Set_Pixel(4, 5, 1, R, G, B);
+ Cube_Set_Pixel(4, 1, 2, R, G, B);
+ Cube_Set_Pixel(4, 2, 1, R, G, B);
+ Cube_Set_Pixel(4, 6, 5, R, G, B);
+ Cube_Set_Pixel(4, 5, 6, R, G, B);
+
+ Cube_Set_Pixel(1, 2, 5, R, G, B);
+ Cube_Set_Pixel(1, 2, 4, R, G, B);
+ Cube_Set_Pixel(1, 2, 3, R, G, B);
+ Cube_Set_Pixel(1, 2, 2, R, G, B);
+ Cube_Set_Pixel(1, 3, 5, R, G, B);
+ Cube_Set_Pixel(1, 3, 2, R, G, B);
+ Cube_Set_Pixel(1, 4, 5, R, G, B);
+ Cube_Set_Pixel(1, 4, 2, R, G, B);
+ Cube_Set_Pixel(1, 5, 5, R, G, B);
+ Cube_Set_Pixel(1, 5, 4, R, G, B);
+ Cube_Set_Pixel(1, 5, 3, R, G, B);
+ Cube_Set_Pixel(1, 5, 2, R, G, B);
+
+ Cube_Set_Pixel(2, 1, 5, R, G, B);
+ Cube_Set_Pixel(2, 1, 4, R, G, B);
+ Cube_Set_Pixel(2, 1, 3, R, G, B);
+ Cube_Set_Pixel(2, 1, 2, R, G, B);
+ Cube_Set_Pixel(2, 6, 5, R, G, B);
+ Cube_Set_Pixel(2, 6, 4, R, G, B);
+ Cube_Set_Pixel(2, 6, 3, R, G, B);
+ Cube_Set_Pixel(2, 6, 2, R, G, B);
+ Cube_Set_Pixel(2, 2, 6, R, G, B);
+ Cube_Set_Pixel(2, 3, 6, R, G, B);
+ Cube_Set_Pixel(2, 4, 6, R, G, B);
+ Cube_Set_Pixel(2, 5, 6, R, G, B);
+ Cube_Set_Pixel(2, 2, 1, R, G, B);
+ Cube_Set_Pixel(2, 3, 1, R, G, B);
+ Cube_Set_Pixel(2, 4, 1, R, G, B);
+ Cube_Set_Pixel(2, 5, 1, R, G, B);
+
+ Cube_Set_Pixel(5, 1, 5, R, G, B);
+ Cube_Set_Pixel(5, 1, 4, R, G, B);
+ Cube_Set_Pixel(5, 1, 3, R, G, B);
+ Cube_Set_Pixel(5, 1, 2, R, G, B);
+ Cube_Set_Pixel(5, 6, 5, R, G, B);
+ Cube_Set_Pixel(5, 6, 4, R, G, B);
+ Cube_Set_Pixel(5, 6, 3, R, G, B);
+ Cube_Set_Pixel(5, 6, 2, R, G, B);
+ Cube_Set_Pixel(5, 2, 6, R, G, B);
+ Cube_Set_Pixel(5, 3, 6, R, G, B);
+ Cube_Set_Pixel(5, 4, 6, R, G, B);
+ Cube_Set_Pixel(5, 5, 6, R, G, B);
+ Cube_Set_Pixel(5, 2, 1, R, G, B);
+ Cube_Set_Pixel(5, 3, 1, R, G, B);
+ Cube_Set_Pixel(5, 4, 1, R, G, B);
+ Cube_Set_Pixel(5, 5, 1, R, G, B);
+
+ Cube_Set_Pixel(6, 2, 5, R, G, B);
+ Cube_Set_Pixel(6, 2, 4, R, G, B);
+ Cube_Set_Pixel(6, 2, 3, R, G, B);
+ Cube_Set_Pixel(6, 2, 2, R, G, B);
+ Cube_Set_Pixel(6, 3, 5, R, G, B);
+ Cube_Set_Pixel(6, 3, 2, R, G, B);
+ Cube_Set_Pixel(6, 4, 5, R, G, B);
+ Cube_Set_Pixel(6, 4, 2, R, G, B);
+ Cube_Set_Pixel(6, 5, 5, R, G, B);
+ Cube_Set_Pixel(6, 5, 4, R, G, B);
+ Cube_Set_Pixel(6, 5, 3, R, G, B);
+ Cube_Set_Pixel(6, 5, 2, R, G, B);
+ break;
+ case 4:
+ Cube_Set_Pixel(0, 2, 5, R, G, B);
+ Cube_Set_Pixel(0, 2, 4, R, G, B);
+ Cube_Set_Pixel(0, 2, 3, R, G, B);
+ Cube_Set_Pixel(0, 2, 2, R, G, B);
+ Cube_Set_Pixel(0, 3, 5, R, G, B);
+ Cube_Set_Pixel(0, 3, 2, R, G, B);
+ Cube_Set_Pixel(0, 4, 5, R, G, B);
+ Cube_Set_Pixel(0, 4, 2, R, G, B);
+ Cube_Set_Pixel(0, 5, 5, R, G, B);
+ Cube_Set_Pixel(0, 5, 4, R, G, B);
+ Cube_Set_Pixel(0, 5, 3, R, G, B);
+ Cube_Set_Pixel(0, 5, 2, R, G, B);
+
+ Cube_Set_Pixel(7, 2, 5, R, G, B);
+ Cube_Set_Pixel(7, 2, 4, R, G, B);
+ Cube_Set_Pixel(7, 2, 3, R, G, B);
+ Cube_Set_Pixel(7, 2, 2, R, G, B);
+ Cube_Set_Pixel(7, 3, 5, R, G, B);
+ Cube_Set_Pixel(7, 3, 2, R, G, B);
+ Cube_Set_Pixel(7, 4, 5, R, G, B);
+ Cube_Set_Pixel(7, 4, 2, R, G, B);
+ Cube_Set_Pixel(7, 5, 5, R, G, B);
+ Cube_Set_Pixel(7, 5, 4, R, G, B);
+ Cube_Set_Pixel(7, 5, 3, R, G, B);
+ Cube_Set_Pixel(7, 5, 2, R, G, B);
+
+ Cube_Set_Pixel(1, 1, 5, R, G, B);
+ Cube_Set_Pixel(1, 1, 4, R, G, B);
+ Cube_Set_Pixel(1, 1, 3, R, G, B);
+ Cube_Set_Pixel(1, 1, 2, R, G, B);
+ Cube_Set_Pixel(1, 6, 5, R, G, B);
+ Cube_Set_Pixel(1, 6, 4, R, G, B);
+ Cube_Set_Pixel(1, 6, 3, R, G, B);
+ Cube_Set_Pixel(1, 6, 2, R, G, B);
+ Cube_Set_Pixel(1, 2, 6, R, G, B);
+ Cube_Set_Pixel(1, 3, 6, R, G, B);
+ Cube_Set_Pixel(1, 4, 6, R, G, B);
+ Cube_Set_Pixel(1, 5, 6, R, G, B);
+ Cube_Set_Pixel(1, 2, 1, R, G, B);
+ Cube_Set_Pixel(1, 3, 1, R, G, B);
+ Cube_Set_Pixel(1, 4, 1, R, G, B);
+ Cube_Set_Pixel(1, 5, 1, R, G, B);
+
+ Cube_Set_Pixel(6, 1, 5, R, G, B);
+ Cube_Set_Pixel(6, 1, 4, R, G, B);
+ Cube_Set_Pixel(6, 1, 3, R, G, B);
+ Cube_Set_Pixel(6, 1, 2, R, G, B);
+ Cube_Set_Pixel(6, 6, 5, R, G, B);
+ Cube_Set_Pixel(6, 6, 4, R, G, B);
+ Cube_Set_Pixel(6, 6, 3, R, G, B);
+ Cube_Set_Pixel(6, 6, 2, R, G, B);
+ Cube_Set_Pixel(6, 2, 6, R, G, B);
+ Cube_Set_Pixel(6, 3, 6, R, G, B);
+ Cube_Set_Pixel(6, 4, 6, R, G, B);
+ Cube_Set_Pixel(6, 5, 6, R, G, B);
+ Cube_Set_Pixel(6, 2, 1, R, G, B);
+ Cube_Set_Pixel(6, 3, 1, R, G, B);
+ Cube_Set_Pixel(6, 4, 1, R, G, B);
+ Cube_Set_Pixel(6, 5, 1, R, G, B);
+
+ Cube_Set_Pixel(2, 0, 5, R, G, B);
+ Cube_Set_Pixel(2, 0, 4, R, G, B);
+ Cube_Set_Pixel(2, 0, 3, R, G, B);
+ Cube_Set_Pixel(2, 0, 2, R, G, B);
+ Cube_Set_Pixel(2, 7, 5, R, G, B);
+ Cube_Set_Pixel(2, 7, 4, R, G, B);
+ Cube_Set_Pixel(2, 7, 3, R, G, B);
+ Cube_Set_Pixel(2, 7, 2, R, G, B);
+ Cube_Set_Pixel(2, 5, 0, R, G, B);
+ Cube_Set_Pixel(2, 4, 0, R, G, B);
+ Cube_Set_Pixel(2, 3, 0, R, G, B);
+ Cube_Set_Pixel(2, 2, 0, R, G, B);
+ Cube_Set_Pixel(2, 5, 7, R, G, B);
+ Cube_Set_Pixel(2, 4, 7, R, G, B);
+ Cube_Set_Pixel(2, 3, 7, R, G, B);
+ Cube_Set_Pixel(2, 2, 7, R, G, B);
+ Cube_Set_Pixel(2, 1, 1, R, G, B);
+ Cube_Set_Pixel(2, 1, 6, R, G, B);
+ Cube_Set_Pixel(2, 6, 1, R, G, B);
+ Cube_Set_Pixel(2, 6, 6, R, G, B);
+
+ Cube_Set_Pixel(5, 0, 5, R, G, B);
+ Cube_Set_Pixel(5, 0, 4, R, G, B);
+ Cube_Set_Pixel(5, 0, 3, R, G, B);
+ Cube_Set_Pixel(5, 0, 2, R, G, B);
+ Cube_Set_Pixel(5, 7, 5, R, G, B);
+ Cube_Set_Pixel(5, 7, 4, R, G, B);
+ Cube_Set_Pixel(5, 7, 3, R, G, B);
+ Cube_Set_Pixel(5, 7, 2, R, G, B);
+ Cube_Set_Pixel(5, 5, 0, R, G, B);
+ Cube_Set_Pixel(5, 4, 0, R, G, B);
+ Cube_Set_Pixel(5, 3, 0, R, G, B);
+ Cube_Set_Pixel(5, 2, 0, R, G, B);
+ Cube_Set_Pixel(5, 5, 7, R, G, B);
+ Cube_Set_Pixel(5, 4, 7, R, G, B);
+ Cube_Set_Pixel(5, 3, 7, R, G, B);
+ Cube_Set_Pixel(5, 2, 7, R, G, B);
+ Cube_Set_Pixel(5, 1, 1, R, G, B);
+ Cube_Set_Pixel(5, 1, 6, R, G, B);
+ Cube_Set_Pixel(5, 6, 1, R, G, B);
+ Cube_Set_Pixel(5, 6, 6, R, G, B);
+
+ Cube_Set_Pixel(3, 0, 2, R, G, B);
+ Cube_Set_Pixel(3, 0, 5, R, G, B);
+ Cube_Set_Pixel(3, 2, 0, R, G, B);
+ Cube_Set_Pixel(3, 5, 0, R, G, B);
+ Cube_Set_Pixel(3, 7, 2, R, G, B);
+ Cube_Set_Pixel(3, 7, 5, R, G, B);
+ Cube_Set_Pixel(3, 2, 7, R, G, B);
+ Cube_Set_Pixel(3, 5, 7, R, G, B);
+ Cube_Set_Pixel(3, 1, 1, R, G, B);
+ Cube_Set_Pixel(3, 1, 6, R, G, B);
+ Cube_Set_Pixel(3, 6, 1, R, G, B);
+ Cube_Set_Pixel(3, 6, 6, R, G, B);
+
+ Cube_Set_Pixel(4, 0, 2, R, G, B);
+ Cube_Set_Pixel(4, 0, 5, R, G, B);
+ Cube_Set_Pixel(4, 2, 0, R, G, B);
+ Cube_Set_Pixel(4, 5, 0, R, G, B);
+ Cube_Set_Pixel(4, 7, 2, R, G, B);
+ Cube_Set_Pixel(4, 7, 5, R, G, B);
+ Cube_Set_Pixel(4, 2, 7, R, G, B);
+ Cube_Set_Pixel(4, 5, 7, R, G, B);
+ Cube_Set_Pixel(4, 1, 1, R, G, B);
+ Cube_Set_Pixel(4, 1, 6, R, G, B);
+ Cube_Set_Pixel(4, 6, 1, R, G, B);
+ Cube_Set_Pixel(4, 6, 6, R, G, B);
+ break;
+ case 5:
+ Cube_Set_Pixel(0, 1, 5, R, G, B);
+ Cube_Set_Pixel(0, 1, 4, R, G, B);
+ Cube_Set_Pixel(0, 1, 3, R, G, B);
+ Cube_Set_Pixel(0, 1, 2, R, G, B);
+ Cube_Set_Pixel(0, 6, 5, R, G, B);
+ Cube_Set_Pixel(0, 6, 4, R, G, B);
+ Cube_Set_Pixel(0, 6, 3, R, G, B);
+ Cube_Set_Pixel(0, 6, 2, R, G, B);
+ Cube_Set_Pixel(0, 2, 6, R, G, B);
+ Cube_Set_Pixel(0, 3, 6, R, G, B);
+ Cube_Set_Pixel(0, 4, 6, R, G, B);
+ Cube_Set_Pixel(0, 5, 6, R, G, B);
+ Cube_Set_Pixel(0, 2, 1, R, G, B);
+ Cube_Set_Pixel(0, 3, 1, R, G, B);
+ Cube_Set_Pixel(0, 4, 1, R, G, B);
+ Cube_Set_Pixel(0, 5, 1, R, G, B);
+
+ Cube_Set_Pixel(1, 0, 2, R, G, B);
+ Cube_Set_Pixel(1, 0, 3, R, G, B);
+ Cube_Set_Pixel(1, 0, 4, R, G, B);
+ Cube_Set_Pixel(1, 0, 5, R, G, B);
+ Cube_Set_Pixel(1, 1, 6, R, G, B);
+ Cube_Set_Pixel(1, 2, 7, R, G, B);
+ Cube_Set_Pixel(1, 3, 7, R, G, B);
+ Cube_Set_Pixel(1, 4, 7, R, G, B);
+ Cube_Set_Pixel(1, 5, 7, R, G, B);
+ Cube_Set_Pixel(1, 6, 6, R, G, B);
+ Cube_Set_Pixel(1, 7, 5, R, G, B);
+ Cube_Set_Pixel(1, 7, 4, R, G, B);
+ Cube_Set_Pixel(1, 7, 3, R, G, B);
+ Cube_Set_Pixel(1, 7, 2, R, G, B);
+ Cube_Set_Pixel(1, 6, 1, R, G, B);
+ Cube_Set_Pixel(1, 5, 0, R, G, B);
+ Cube_Set_Pixel(1, 4, 0, R, G, B);
+ Cube_Set_Pixel(1, 3, 0, R, G, B);
+ Cube_Set_Pixel(1, 2, 0, R, G, B);
+ Cube_Set_Pixel(1, 1, 1, R, G, B);
+
+ Cube_Set_Pixel(2, 0, 1, R, G, B);
+ Cube_Set_Pixel(2, 1, 0, R, G, B);
+ Cube_Set_Pixel(2, 0, 6, R, G, B);
+ Cube_Set_Pixel(2, 1, 7, R, G, B);
+ Cube_Set_Pixel(2, 6, 7, R, G, B);
+ Cube_Set_Pixel(2, 7, 6, R, G, B);
+ Cube_Set_Pixel(2, 6, 0, R, G, B);
+ Cube_Set_Pixel(2, 7, 1, R, G, B);
+
+ Cube_Set_Pixel(3, 0, 1, R, G, B);
+ Cube_Set_Pixel(3, 1, 0, R, G, B);
+ Cube_Set_Pixel(3, 0, 6, R, G, B);
+ Cube_Set_Pixel(3, 1, 7, R, G, B);
+ Cube_Set_Pixel(3, 6, 7, R, G, B);
+ Cube_Set_Pixel(3, 7, 6, R, G, B);
+ Cube_Set_Pixel(3, 6, 0, R, G, B);
+ Cube_Set_Pixel(3, 7, 1, R, G, B);
+
+ Cube_Set_Pixel(4, 0, 1, R, G, B);
+ Cube_Set_Pixel(4, 1, 0, R, G, B);
+ Cube_Set_Pixel(4, 0, 6, R, G, B);
+ Cube_Set_Pixel(4, 1, 7, R, G, B);
+ Cube_Set_Pixel(4, 6, 7, R, G, B);
+ Cube_Set_Pixel(4, 7, 6, R, G, B);
+ Cube_Set_Pixel(4, 6, 0, R, G, B);
+ Cube_Set_Pixel(4, 7, 1, R, G, B);
+
+ Cube_Set_Pixel(5, 0, 1, R, G, B);
+ Cube_Set_Pixel(5, 1, 0, R, G, B);
+ Cube_Set_Pixel(5, 0, 6, R, G, B);
+ Cube_Set_Pixel(5, 1, 7, R, G, B);
+ Cube_Set_Pixel(5, 6, 7, R, G, B);
+ Cube_Set_Pixel(5, 7, 6, R, G, B);
+ Cube_Set_Pixel(5, 6, 0, R, G, B);
+ Cube_Set_Pixel(5, 7, 1, R, G, B);
+
+
+ Cube_Set_Pixel(6, 0, 2, R, G, B);
+ Cube_Set_Pixel(6, 0, 3, R, G, B);
+ Cube_Set_Pixel(6, 0, 4, R, G, B);
+ Cube_Set_Pixel(6, 0, 5, R, G, B);
+ Cube_Set_Pixel(6, 1, 6, R, G, B);
+ Cube_Set_Pixel(6, 2, 7, R, G, B);
+ Cube_Set_Pixel(6, 3, 7, R, G, B);
+ Cube_Set_Pixel(6, 4, 7, R, G, B);
+ Cube_Set_Pixel(6, 5, 7, R, G, B);
+ Cube_Set_Pixel(6, 6, 6, R, G, B);
+ Cube_Set_Pixel(6, 7, 5, R, G, B);
+ Cube_Set_Pixel(6, 7, 4, R, G, B);
+ Cube_Set_Pixel(6, 7, 3, R, G, B);
+ Cube_Set_Pixel(6, 7, 2, R, G, B);
+ Cube_Set_Pixel(6, 6, 1, R, G, B);
+ Cube_Set_Pixel(6, 5, 0, R, G, B);
+ Cube_Set_Pixel(6, 4, 0, R, G, B);
+ Cube_Set_Pixel(6, 3, 0, R, G, B);
+ Cube_Set_Pixel(6, 2, 0, R, G, B);
+ Cube_Set_Pixel(6, 1, 1, R, G, B);
+
+ Cube_Set_Pixel(7, 1, 5, R, G, B);
+ Cube_Set_Pixel(7, 1, 4, R, G, B);
+ Cube_Set_Pixel(7, 1, 3, R, G, B);
+ Cube_Set_Pixel(7, 1, 2, R, G, B);
+ Cube_Set_Pixel(7, 6, 5, R, G, B);
+ Cube_Set_Pixel(7, 6, 4, R, G, B);
+ Cube_Set_Pixel(7, 6, 3, R, G, B);
+ Cube_Set_Pixel(7, 6, 2, R, G, B);
+ Cube_Set_Pixel(7, 2, 6, R, G, B);
+ Cube_Set_Pixel(7, 3, 6, R, G, B);
+ Cube_Set_Pixel(7, 4, 6, R, G, B);
+ Cube_Set_Pixel(7, 5, 6, R, G, B);
+ Cube_Set_Pixel(7, 2, 1, R, G, B);
+ Cube_Set_Pixel(7, 3, 1, R, G, B);
+ Cube_Set_Pixel(7, 4, 1, R, G, B);
+ Cube_Set_Pixel(7, 5, 1, R, G, B);
+ break;
+ case 6:
+ Cube_Set_Pixel(0, 0, 2, R, G, B);
+ Cube_Set_Pixel(0, 0, 3, R, G, B);
+ Cube_Set_Pixel(0, 0, 4, R, G, B);
+ Cube_Set_Pixel(0, 0, 5, R, G, B);
+ Cube_Set_Pixel(0, 1, 1, R, G, B);
+ Cube_Set_Pixel(0, 1, 6, R, G, B);
+ Cube_Set_Pixel(0, 2, 0, R, G, B);
+ Cube_Set_Pixel(0, 2, 7, R, G, B);
+ Cube_Set_Pixel(0, 3, 0, R, G, B);
+ Cube_Set_Pixel(0, 3, 7, R, G, B);
+ Cube_Set_Pixel(0, 4, 0, R, G, B);
+ Cube_Set_Pixel(0, 4, 7, R, G, B);
+ Cube_Set_Pixel(0, 5, 0, R, G, B);
+ Cube_Set_Pixel(0, 5, 7, R, G, B);
+ Cube_Set_Pixel(0, 6, 6, R, G, B);
+ Cube_Set_Pixel(0, 6, 1, R, G, B);
+ Cube_Set_Pixel(0, 7, 2, R, G, B);
+ Cube_Set_Pixel(0, 7, 3, R, G, B);
+ Cube_Set_Pixel(0, 7, 4, R, G, B);
+ Cube_Set_Pixel(0, 7, 5, R, G, B);
+
+ Cube_Set_Pixel(1, 0, 1, R, G, B);
+ Cube_Set_Pixel(1, 1, 0, R, G, B);
+ Cube_Set_Pixel(1, 0, 6, R, G, B);
+ Cube_Set_Pixel(1, 1, 7, R, G, B);
+ Cube_Set_Pixel(1, 6, 7, R, G, B);
+ Cube_Set_Pixel(1, 7, 6, R, G, B);
+ Cube_Set_Pixel(1, 6, 0, R, G, B);
+ Cube_Set_Pixel(1, 7, 1, R, G, B);
+
+ Cube_Set_Pixel(2, 0, 0, R, G, B);
+ Cube_Set_Pixel(2, 0, 7, R, G, B);
+ Cube_Set_Pixel(2, 7, 7, R, G, B);
+ Cube_Set_Pixel(2, 7, 0, R, G, B);
+
+ Cube_Set_Pixel(3, 0, 0, R, G, B);
+ Cube_Set_Pixel(3, 0, 7, R, G, B);
+ Cube_Set_Pixel(3, 7, 7, R, G, B);
+ Cube_Set_Pixel(3, 7, 0, R, G, B);
+
+ Cube_Set_Pixel(4, 0, 0, R, G, B);
+ Cube_Set_Pixel(4, 0, 7, R, G, B);
+ Cube_Set_Pixel(4, 7, 7, R, G, B);
+ Cube_Set_Pixel(4, 7, 0, R, G, B);
+
+ Cube_Set_Pixel(5, 0, 0, R, G, B);
+ Cube_Set_Pixel(5, 0, 7, R, G, B);
+ Cube_Set_Pixel(5, 7, 7, R, G, B);
+ Cube_Set_Pixel(5, 7, 0, R, G, B);
+
+ Cube_Set_Pixel(6, 0, 1, R, G, B);
+ Cube_Set_Pixel(6, 1, 0, R, G, B);
+ Cube_Set_Pixel(6, 0, 6, R, G, B);
+ Cube_Set_Pixel(6, 1, 7, R, G, B);
+ Cube_Set_Pixel(6, 6, 7, R, G, B);
+ Cube_Set_Pixel(6, 7, 6, R, G, B);
+ Cube_Set_Pixel(6, 6, 0, R, G, B);
+ Cube_Set_Pixel(6, 7, 1, R, G, B);
+
+ Cube_Set_Pixel(7, 0, 2, R, G, B);
+ Cube_Set_Pixel(7, 0, 3, R, G, B);
+ Cube_Set_Pixel(7, 0, 4, R, G, B);
+ Cube_Set_Pixel(7, 0, 5, R, G, B);
+ Cube_Set_Pixel(7, 1, 1, R, G, B);
+ Cube_Set_Pixel(7, 1, 6, R, G, B);
+ Cube_Set_Pixel(7, 2, 0, R, G, B);
+ Cube_Set_Pixel(7, 2, 7, R, G, B);
+ Cube_Set_Pixel(7, 3, 0, R, G, B);
+ Cube_Set_Pixel(7, 3, 7, R, G, B);
+ Cube_Set_Pixel(7, 4, 0, R, G, B);
+ Cube_Set_Pixel(7, 4, 7, R, G, B);
+ Cube_Set_Pixel(7, 5, 0, R, G, B);
+ Cube_Set_Pixel(7, 5, 7, R, G, B);
+ Cube_Set_Pixel(7, 6, 6, R, G, B);
+ Cube_Set_Pixel(7, 6, 1, R, G, B);
+ Cube_Set_Pixel(7, 7, 2, R, G, B);
+ Cube_Set_Pixel(7, 7, 3, R, G, B);
+ Cube_Set_Pixel(7, 7, 4, R, G, B);
+ Cube_Set_Pixel(7, 7, 5, R, G, B);
+ break;
+ case 7:
+ Cube_Set_Pixel(0, 0, 1, R, G, B);
+ Cube_Set_Pixel(0, 1, 0, R, G, B);
+ Cube_Set_Pixel(0, 0, 6, R, G, B);
+ Cube_Set_Pixel(0, 1, 7, R, G, B);
+ Cube_Set_Pixel(0, 6, 7, R, G, B);
+ Cube_Set_Pixel(0, 7, 6, R, G, B);
+ Cube_Set_Pixel(0, 7, 1, R, G, B);
+ Cube_Set_Pixel(0, 6, 0, R, G, B);
+
+ Cube_Set_Pixel(1, 0, 0, R, G, B);
+ Cube_Set_Pixel(1, 0, 7, R, G, B);
+ Cube_Set_Pixel(1, 7, 7, R, G, B);
+ Cube_Set_Pixel(1, 7, 0, R, G, B);
+
+ Cube_Set_Pixel(6, 0, 0, R, G, B);
+ Cube_Set_Pixel(6, 0, 7, R, G, B);
+ Cube_Set_Pixel(6, 7, 7, R, G, B);
+ Cube_Set_Pixel(6, 7, 0, R, G, B);
+
+ Cube_Set_Pixel(7, 0, 1, R, G, B);
+ Cube_Set_Pixel(7, 1, 0, R, G, B);
+ Cube_Set_Pixel(7, 0, 6, R, G, B);
+ Cube_Set_Pixel(7, 1, 7, R, G, B);
+ Cube_Set_Pixel(7, 6, 7, R, G, B);
+ Cube_Set_Pixel(7, 7, 6, R, G, B);
+ Cube_Set_Pixel(7, 7, 1, R, G, B);
+ Cube_Set_Pixel(7, 6, 0, R, G, B);
+ break;
+ case 8:
+ Cube_Set_Pixel(0, 0, 0, R, G, B);
+ Cube_Set_Pixel(0, 0, 7, R, G, B);
+ Cube_Set_Pixel(0, 7, 7, R, G, B);
+ Cube_Set_Pixel(0, 7, 0, R, G, B);
+
+ Cube_Set_Pixel(7, 0, 0, R, G, B);
+ Cube_Set_Pixel(7, 0, 7, R, G, B);
+ Cube_Set_Pixel(7, 7, 7, R, G, B);
+ Cube_Set_Pixel(7, 7, 0, R, G, B);
+ break;
+ default:
+ break;
+ }
+}
+
+void Cube_Set_Shell(uint8_t layer, uint8_t R, uint8_t G, uint8_t B) {
+ // Sets the specified shell to the specific color
+ // Shell 0 is the outermost layer, 3 is the innermost cube of pixels
+ uint8_t i, j, k;
+
+ for (i = 0; i < CUBE_LAYER_COUNT; i++) {
+ if ((layer == 0 || layer == 4)&&(i == 0 || i == 7)) {
+ Cube_Set_Layer(i,R,G,B);
+ } else if ((layer == 1 || layer == 4)&&(i == 1 || i == 6)) {
+ for (j = 1; j < CUBE_ROW_COUNT-1; j++)
+ for (k = 1; k < CUBE_COLUMN_COUNT-1; k++)
+ Cube_Set_Pixel(i,j,k,R,G,B);
+ } else if ((layer == 2 || layer == 4)&&(i == 2 || i == 5)) {
+ for (j = 2; j < CUBE_ROW_COUNT-2; j++)
+ for (k = 2; k < CUBE_COLUMN_COUNT-2; k++)
+ Cube_Set_Pixel(i,j,k,R,G,B);
+ } else if ((layer == 3 || layer == 4)&&(i == 3 || i == 4)) {
+ for (j = 3; j < CUBE_ROW_COUNT-3; j++)
+ for (k = 3; k < CUBE_COLUMN_COUNT-3; k++)
+ Cube_Set_Pixel(i,j,k,R,G,B);
+ }
+
+ if ((layer == 0 || layer == 4)&&(i > 0 && i < 8)) {
+ for (j = 0; j < 8; j++) {
+ Cube_Set_Pixel(i,j,0,R,G,B);
+ Cube_Set_Pixel(i,j,7,R,G,B);
+ Cube_Set_Pixel(i,0,j,R,G,B);
+ Cube_Set_Pixel(i,7,j,R,G,B);
+ }
+ }
+ if ((layer == 1 || layer == 4)&&(i > 1 && i < 7)) {
+ for (j = 1; j < 7; j++) {
+ Cube_Set_Pixel(i,j,1,R,G,B);
+ Cube_Set_Pixel(i,j,6,R,G,B);
+ Cube_Set_Pixel(i,1,j,R,G,B);
+ Cube_Set_Pixel(i,6,j,R,G,B);
+ }
+ }
+ if ((layer == 2 || layer == 4)&&(i > 2 && i < 6)) {
+ for (j = 2; j < 6; j++) {
+ Cube_Set_Pixel(i,j,2,R,G,B);
+ Cube_Set_Pixel(i,j,5,R,G,B);
+ Cube_Set_Pixel(i,2,j,R,G,B);
+ Cube_Set_Pixel(i,5,j,R,G,B);
+ }
+ }
+ }
+}
+
+void Cube_Rotate_Shell(uint8_t shell, uint8_t direction) {
+ // Shell is the layer to rotate, with the outermost being 0
+ uint8_t layer;
+ uint16_t origin_R, origin_G, origin_B;
+ for (layer = 0; layer < CUBE_LAYER_COUNT; layer++) {
+ if (direction) {
+ switch(shell) {
+ case 0:
+ // Rotate outermost layer
+ Cube_Get_Pixel(layer, 0, 0, &origin_R, &origin_G, &origin_B);
+ Cube_Move_Pixel(layer, 0, 1, layer, 0, 0);
+ Cube_Move_Pixel(layer, 0, 2, layer, 0, 1);
+ Cube_Move_Pixel(layer, 0, 3, layer, 0, 2);
+ Cube_Move_Pixel(layer, 0, 4, layer, 0, 3);
+ Cube_Move_Pixel(layer, 0, 5, layer, 0, 4);
+ Cube_Move_Pixel(layer, 0, 6, layer, 0, 5);
+ Cube_Move_Pixel(layer, 0, 7, layer, 0, 6);
+ Cube_Move_Pixel(layer, 1, 7, layer, 0, 7);
+ Cube_Move_Pixel(layer, 2, 7, layer, 1, 7);
+ Cube_Move_Pixel(layer, 3, 7, layer, 2, 7);
+ Cube_Move_Pixel(layer, 4, 7, layer, 3, 7);
+ Cube_Move_Pixel(layer, 5, 7, layer, 4, 7);
+ Cube_Move_Pixel(layer, 6, 7, layer, 5, 7);
+ Cube_Move_Pixel(layer, 7, 7, layer, 6, 7);
+ Cube_Move_Pixel(layer, 7, 6, layer, 7, 7);
+ Cube_Move_Pixel(layer, 7, 5, layer, 7, 6);
+ Cube_Move_Pixel(layer, 7, 4, layer, 7, 5);
+ Cube_Move_Pixel(layer, 7, 3, layer, 7, 4);
+ Cube_Move_Pixel(layer, 7, 2, layer, 7, 3);
+ Cube_Move_Pixel(layer, 7, 1, layer, 7, 2);
+ Cube_Move_Pixel(layer, 7, 0, layer, 7, 1);
+ Cube_Move_Pixel(layer, 6, 0, layer, 7, 0);
+ Cube_Move_Pixel(layer, 5, 0, layer, 6, 0);
+ Cube_Move_Pixel(layer, 4, 0, layer, 5, 0);
+ Cube_Move_Pixel(layer, 3, 0, layer, 4, 0);
+ Cube_Move_Pixel(layer, 2, 0, layer, 3, 0);
+ Cube_Move_Pixel(layer, 1, 0, layer, 2, 0);
+ Cube_Set_Pixel(layer, 1, 0, origin_R, origin_G, origin_B);
+ break;
+ case 1:
+ // Rotate second to outermost layer
+ Cube_Get_Pixel(layer, 1, 1, &origin_R, &origin_G, &origin_B);
+ Cube_Move_Pixel(layer, 1, 2, layer, 1, 1);
+ Cube_Move_Pixel(layer, 1, 3, layer, 1, 2);
+ Cube_Move_Pixel(layer, 1, 4, layer, 1, 3);
+ Cube_Move_Pixel(layer, 1, 5, layer, 1, 4);
+ Cube_Move_Pixel(layer, 1, 6, layer, 1, 5);
+ Cube_Move_Pixel(layer, 2, 6, layer, 1, 6);
+ Cube_Move_Pixel(layer, 3, 6, layer, 2, 6);
+ Cube_Move_Pixel(layer, 4, 6, layer, 3, 6);
+ Cube_Move_Pixel(layer, 5, 6, layer, 4, 6);
+ Cube_Move_Pixel(layer, 6, 6, layer, 5, 6);
+ Cube_Move_Pixel(layer, 6, 5, layer, 6, 6);
+ Cube_Move_Pixel(layer, 6, 4, layer, 6, 5);
+ Cube_Move_Pixel(layer, 6, 3, layer, 6, 4);
+ Cube_Move_Pixel(layer, 6, 2, layer, 6, 3);
+ Cube_Move_Pixel(layer, 6, 1, layer, 6, 2);
+ Cube_Move_Pixel(layer, 5, 1, layer, 6, 1);
+ Cube_Move_Pixel(layer, 4, 1, layer, 5, 1);
+ Cube_Move_Pixel(layer, 3, 1, layer, 4, 1);
+ Cube_Move_Pixel(layer, 2, 1, layer, 3, 1);
+ Cube_Set_Pixel(layer, 2, 1, origin_R, origin_G, origin_B);
+ break;
+ case 2:
+ // Rotate second to innermost layer
+ Cube_Get_Pixel(layer, 2, 2, &origin_R, &origin_G, &origin_B);
+ Cube_Move_Pixel(layer, 2, 3, layer, 2, 2);
+ Cube_Move_Pixel(layer, 2, 4, layer, 2, 3);
+ Cube_Move_Pixel(layer, 2, 5, layer, 2, 4);
+ Cube_Move_Pixel(layer, 3, 5, layer, 2, 5);
+ Cube_Move_Pixel(layer, 4, 5, layer, 3, 5);
+ Cube_Move_Pixel(layer, 5, 5, layer, 4, 5);
+ Cube_Move_Pixel(layer, 5, 4, layer, 5, 5);
+ Cube_Move_Pixel(layer, 5, 3, layer, 5, 4);
+ Cube_Move_Pixel(layer, 5, 2, layer, 5, 3);
+ Cube_Move_Pixel(layer, 4, 2, layer, 5, 2);
+ Cube_Move_Pixel(layer, 3, 2, layer, 4, 2);
+ Cube_Set_Pixel(layer, 3, 2, origin_R, origin_G, origin_B);
+ break;
+ case 3:
+ // Rotate innermost layer
+ Cube_Get_Pixel(layer, 3, 3, &origin_R, &origin_G, &origin_B);
+ Cube_Move_Pixel(layer, 3, 4, layer, 3, 3);
+ Cube_Move_Pixel(layer, 4, 4, layer, 3, 4);
+ Cube_Move_Pixel(layer, 4, 3, layer, 4, 4);
+ Cube_Set_Pixel(layer, 4, 3, origin_R, origin_G, origin_B);
+ break;
+ }
+ } else {
+ switch(shell) {
+ case 0:
+ // Rotate outermost layer
+ Cube_Get_Pixel(layer, 0, 0, &origin_R, &origin_G, &origin_B);
+ Cube_Move_Pixel(layer, 1, 0, layer, 0, 0);
+ Cube_Move_Pixel(layer, 2, 0, layer, 1, 0);
+ Cube_Move_Pixel(layer, 3, 0, layer, 2, 0);
+ Cube_Move_Pixel(layer, 4, 0, layer, 3, 0);
+ Cube_Move_Pixel(layer, 5, 0, layer, 4, 0);
+ Cube_Move_Pixel(layer, 6, 0, layer, 5, 0);
+ Cube_Move_Pixel(layer, 7, 0, layer, 6, 0);
+ Cube_Move_Pixel(layer, 7, 1, layer, 7, 0);
+ Cube_Move_Pixel(layer, 7, 2, layer, 7, 1);
+ Cube_Move_Pixel(layer, 7, 3, layer, 7, 2);
+ Cube_Move_Pixel(layer, 7, 4, layer, 7, 3);
+ Cube_Move_Pixel(layer, 7, 5, layer, 7, 4);
+ Cube_Move_Pixel(layer, 7, 6, layer, 7, 5);
+ Cube_Move_Pixel(layer, 7, 7, layer, 7, 6);
+ Cube_Move_Pixel(layer, 6, 7, layer, 7, 7);
+ Cube_Move_Pixel(layer, 5, 7, layer, 6, 7);
+ Cube_Move_Pixel(layer, 4, 7, layer, 5, 7);
+ Cube_Move_Pixel(layer, 3, 7, layer, 4, 7);
+ Cube_Move_Pixel(layer, 2, 7, layer, 3, 7);
+ Cube_Move_Pixel(layer, 1, 7, layer, 2, 7);
+ Cube_Move_Pixel(layer, 0, 7, layer, 1, 7);
+ Cube_Move_Pixel(layer, 0, 6, layer, 0, 7);
+ Cube_Move_Pixel(layer, 0, 5, layer, 0, 6);
+ Cube_Move_Pixel(layer, 0, 4, layer, 0, 5);
+ Cube_Move_Pixel(layer, 0, 3, layer, 0, 4);
+ Cube_Move_Pixel(layer, 0, 2, layer, 0, 3);
+ Cube_Move_Pixel(layer, 0, 1, layer, 0, 2);
+ Cube_Set_Pixel(layer, 0, 1, origin_R, origin_G, origin_B);
+ break;
+ case 1:
+ // Rotate second to outermost layer
+ Cube_Get_Pixel(layer, 1, 1, &origin_R, &origin_G, &origin_B);
+ Cube_Move_Pixel(layer, 2, 1, layer, 1, 1);
+ Cube_Move_Pixel(layer, 3, 1, layer, 2, 1);
+ Cube_Move_Pixel(layer, 4, 1, layer, 3, 1);
+ Cube_Move_Pixel(layer, 5, 1, layer, 4, 1);
+ Cube_Move_Pixel(layer, 6, 1, layer, 5, 1);
+ Cube_Move_Pixel(layer, 6, 2, layer, 6, 1);
+ Cube_Move_Pixel(layer, 6, 3, layer, 6, 2);
+ Cube_Move_Pixel(layer, 6, 4, layer, 6, 3);
+ Cube_Move_Pixel(layer, 6, 5, layer, 6, 4);
+ Cube_Move_Pixel(layer, 6, 6, layer, 6, 5);
+ Cube_Move_Pixel(layer, 5, 6, layer, 6, 6);
+ Cube_Move_Pixel(layer, 4, 6, layer, 5, 6);
+ Cube_Move_Pixel(layer, 3, 6, layer, 4, 6);
+ Cube_Move_Pixel(layer, 2, 6, layer, 3, 6);
+ Cube_Move_Pixel(layer, 1, 6, layer, 2, 6);
+ Cube_Move_Pixel(layer, 1, 5, layer, 1, 6);
+ Cube_Move_Pixel(layer, 1, 4, layer, 1, 5);
+ Cube_Move_Pixel(layer, 1, 3, layer, 1, 4);
+ Cube_Move_Pixel(layer, 1, 2, layer, 1, 3);
+ Cube_Set_Pixel(layer, 1, 2, origin_R, origin_G, origin_B);
+ break;
+ case 2:
+ // Rotate second to innermost layer
+ Cube_Get_Pixel(layer, 2, 2, &origin_R, &origin_G, &origin_B);
+ Cube_Move_Pixel(layer, 3, 2, layer, 2, 2);
+ Cube_Move_Pixel(layer, 4, 2, layer, 3, 2);
+ Cube_Move_Pixel(layer, 5, 2, layer, 4, 2);
+ Cube_Move_Pixel(layer, 5, 3, layer, 5, 2);
+ Cube_Move_Pixel(layer, 5, 4, layer, 5, 3);
+ Cube_Move_Pixel(layer, 5, 5, layer, 5, 4);
+ Cube_Move_Pixel(layer, 4, 5, layer, 5, 5);
+ Cube_Move_Pixel(layer, 3, 5, layer, 4, 5);
+ Cube_Move_Pixel(layer, 2, 5, layer, 3, 5);
+ Cube_Move_Pixel(layer, 2, 4, layer, 2, 5);
+ Cube_Move_Pixel(layer, 2, 3, layer, 2, 4);
+ Cube_Set_Pixel(layer, 2, 3, origin_R, origin_G, origin_B);
+ break;
+ case 3:
+ // Rotate innermost layer
+ Cube_Get_Pixel(layer, 3, 3, &origin_R, &origin_G, &origin_B);
+ Cube_Move_Pixel(layer, 4, 3, layer, 3, 3);
+ Cube_Move_Pixel(layer, 4, 4, layer, 4, 3);
+ Cube_Move_Pixel(layer, 3, 4, layer, 4, 4);
+ Cube_Set_Pixel(layer, 3, 4, origin_R, origin_G, origin_B);
+ break;
+ }
+ }
+ }
+}
+
+void Cube_Rotate(uint8_t direction) {
+ // Rotate outermost layer
+ Cube_Rotate_Shell(0, direction);
+ // Rotate second to outermost layer
+ if ((cube_data_ptr->rotation_counter != 1) && (cube_data_ptr->rotation_counter != 5)) {
+ Cube_Rotate_Shell(1, direction);
+ }
+ // Rotate second to innermost layer
+ if ((cube_data_ptr->rotation_counter != 0) && (cube_data_ptr->rotation_counter != 2) &&
+ (cube_data_ptr->rotation_counter != 4) && (cube_data_ptr->rotation_counter != 6)) {
+ Cube_Rotate_Shell(2, direction);
+ }
+ // Rotate innermost layer
+ if ((cube_data_ptr->rotation_counter == 3) || (cube_data_ptr->rotation_counter == 7)) {
+ Cube_Rotate_Shell(3, direction);
+ }
+
+ if (direction == 0) {
+ cube_data_ptr->rotation_counter = (cube_data_ptr->rotation_counter == CUBE_ROTATIONS - 1)
+ ? 0 : cube_data_ptr->rotation_counter + 1;
+ } else {
+ cube_data_ptr->rotation_counter = (cube_data_ptr->rotation_counter == 0)
+ ? CUBE_ROTATIONS - 1 : cube_data_ptr->rotation_counter - 1;
+ }
+}
+
+void Cube_Shift_Row(uint8_t direction) {
+ // Shifts the display by an entire row
+ int i, j, k;
+ if (direction) {
+ // Shift values in each row by one
+ for (i = CUBE_ROW_COUNT - 1; i >= 0; i--) { // Row
+ for (j = 0; j < CUBE_COLUMN_COUNT; j++) {
+ for (k = 0; k < CUBE_LAYER_COUNT; k++) {
+ Cube_Move_Pixel(k, i - 1, j, k, i, j);
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < CUBE_ROW_COUNT - 1; i++) {
+ for (j = 0; j < CUBE_COLUMN_COUNT; j++) {
+ for (k = 0; k < CUBE_LAYER_COUNT; k++) {
+ Cube_Move_Pixel(k, i + 1, j, k, i, j);
+ }
+ }
+ }
+ }
+}
+
+void Cube_Shift_Waterfall(uint8_t *values) {
+ // Takes an array of 8 values and sets them to the column height
+ // Each column is set to a manually specified color
+ uint8_t i, j;
+ uint8_t update_row = CUBE_ROW_COUNT - 1;
+
+ // First shift the rows
+ Cube_Shift_Row(0);
+
+ // Then update the empty row
+ for (i = 0; i < CUBE_COLUMN_COUNT; i++) {
+ for (j = 0; j < CUBE_LAYER_COUNT; j++) {
+ if (j < values[i] % 9) {
+ // Specify the color for each column
+ if (i == 0)
+ Cube_Set_Pixel(j, update_row, i, RED);
+ else if (i == 1)
+ Cube_Set_Pixel(j, update_row, i, ORANGE);
+ else if (i == 2)
+ Cube_Set_Pixel(j, update_row, i, YELLOW);
+ else if (i == 3)
+ Cube_Set_Pixel(j, update_row, i, GREEN);
+ else if (i == 4)
+ Cube_Set_Pixel(j, update_row, i, TEAL);
+ else if (i == 5)
+ Cube_Set_Pixel(j, update_row, i, BLUE);
+ else if (i == 6)
+ Cube_Set_Pixel(j, update_row, i, PURPLE);
+ else
+ Cube_Set_Pixel(j, update_row, i, WHITE);
+ } else {
+ Cube_Set_Pixel(j, update_row, i, CLEAR);
+ }
+ }
+ }
+}
+
+void Cube_Shift_Waterfall2(uint8_t *values) {
+ // Takes an array of 8 values and sets them to the column height
+ // Each layer is set to a manually specified color
+ uint8_t i, j;
+ uint8_t update_row = CUBE_ROW_COUNT - 1;
+
+ // First shift the rows
+ Cube_Shift_Row(0);
+
+ // Then update the empty row
+ for (i = 0; i < CUBE_COLUMN_COUNT; i++) {
+ for (j = 0; j < CUBE_LAYER_COUNT; j++) {
+ if (j < values[i] % 9) {
+ // Specify the color for each layer
+ if (j == 7)
+ Cube_Set_Pixel(j, update_row, i, RED);
+ else if (j == 6)
+ Cube_Set_Pixel(j, update_row, i, ORANGE);
+ else if (j == 5)
+ Cube_Set_Pixel(j, update_row, i, YELLOW);
+ else if (j == 4)
+ Cube_Set_Pixel(j, update_row, i, GREEN);
+ else if (j == 3)
+ Cube_Set_Pixel(j, update_row, i, TEAL);
+ else if (j == 2)
+ Cube_Set_Pixel(j, update_row, i, BLUE);
+ else if (j == 1)
+ Cube_Set_Pixel(j, update_row, i, PURPLE);
+ else
+ Cube_Set_Pixel(j, update_row, i, WHITE);
+ } else {
+ Cube_Set_Pixel(j, update_row, i, CLEAR);
+ }
+ }
+ }
+}
+
+///////////////////////////////
+// Overlay control functions //
+///////////////////////////////
+
+void Cube_Overlay_Clear(void) {
+ uint16_t i,j;
+ for (i = 0; i < CUBE_LAYER_COUNT; i++) {
+ for (j = 0; j < GCS_LAYER_SIZE; j++) {
+ cube_data_ptr->GCS_OVERLAY[i][j] = 0x00;
+ }
+ }
+}
+
+void Cube_Overlay_Set_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t R, uint16_t G, uint16_t B) {
+ // Set the specified pixel to the given color
+ R &= 0x0FFF;
+ G &= 0x0FFF;
+ B &= 0x0FFF;
+ uint16_t var = row * GCS_REG_SIZE + (column / 2 * 9);
+ switch (column % 2) {
+ case 0:
+ cube_data_ptr->GCS_OVERLAY[layer][var+0] = R & 0xFF;
+ cube_data_ptr->GCS_OVERLAY[layer][var+1] = (G << 4) | (R >> 8);
+ cube_data_ptr->GCS_OVERLAY[layer][var+2] = G >> 4;
+ cube_data_ptr->GCS_OVERLAY[layer][var+3] = B & 0xFF;
+ cube_data_ptr->GCS_OVERLAY[layer][var+4] = (cube_data_ptr->GCS_OVERLAY[layer][var+4] & 0xF0) | (B >> 8);
+ break;
+ case 1:
+ cube_data_ptr->GCS_OVERLAY[layer][var+4] = (cube_data_ptr->GCS_OVERLAY[layer][var+4] & 0x0F) | (R << 4);
+ cube_data_ptr->GCS_OVERLAY[layer][var+5] = R >> 4;
+ cube_data_ptr->GCS_OVERLAY[layer][var+6] = G & 0xFF;
+ cube_data_ptr->GCS_OVERLAY[layer][var+7] = (B << 4) | (G >> 8);
+ cube_data_ptr->GCS_OVERLAY[layer][var+8] = B >> 4;
+ break;
+ }
+}
+
+void Cube_Overlay_Get_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t* R, uint16_t* G, uint16_t* B) {
+ uint16_t var = row * GCS_REG_SIZE + (column / 2 * 9);
+ switch (column % 2) {
+ // Concatenate lower byte and upper byte of each color channel
+ case 0:
+ *R = cube_data_ptr->GCS_OVERLAY[layer][var+0] | ((cube_data_ptr->GCS_OVERLAY[layer][var+1] & 0x0F) << 8);
+ *G = (cube_data_ptr->GCS_OVERLAY[layer][var+1] >> 4) | (cube_data_ptr->GCS_OVERLAY[layer][var+2] << 4);
+ *B = cube_data_ptr->GCS_OVERLAY[layer][var+3] | ((cube_data_ptr->GCS_OVERLAY[layer][var+4] & 0x0F) << 8);
+ break;
+ case 1:
+ *R = (cube_data_ptr->GCS_OVERLAY[layer][var+4] >> 4) | (cube_data_ptr->GCS_OVERLAY[layer][var+5] << 4);
+ *G = cube_data_ptr->GCS_OVERLAY[layer][var+6] | ((cube_data_ptr->GCS_OVERLAY[layer][var+7] & 0x0F) << 8);
+ *B = (cube_data_ptr->GCS_OVERLAY[layer][var+7] >> 4) | (cube_data_ptr->GCS_OVERLAY[layer][var+8] << 4);
+ break;
+ }
+}
+
+void Cube_Overlay_Move_Pixel(uint8_t layer1, uint8_t row1, uint8_t column1, uint8_t layer2, uint8_t row2, uint8_t column2) {
+ // Copies data from pixel 1 to pixel 2
+ // Note: destination pixel value is overwritten
+ uint16_t prev_R, prev_G, prev_B;
+ Cube_Overlay_Get_Pixel(layer1, row1, column1, &prev_R, &prev_G, &prev_B);
+ Cube_Overlay_Set_Pixel(layer2, row2, column2, prev_R, prev_G, prev_B);
+}
+
+void Cube_Overlay_Rotate_Shell(uint8_t shell, uint8_t direction) {
+ // Shell is the layer to rotate, with the outermost being 0
+ uint8_t layer;
+ uint16_t origin_R, origin_G, origin_B;;
+ for (layer = 0; layer < CUBE_LAYER_COUNT; layer++) {
+ if (direction) {
+ switch(shell) {
+ case 0:
+ // Rotate outermost layer
+ Cube_Overlay_Get_Pixel(layer, 0, 0, &origin_R, &origin_G, &origin_B);
+ Cube_Overlay_Move_Pixel(layer, 0, 1, layer, 0, 0);
+ Cube_Overlay_Move_Pixel(layer, 0, 2, layer, 0, 1);
+ Cube_Overlay_Move_Pixel(layer, 0, 3, layer, 0, 2);
+ Cube_Overlay_Move_Pixel(layer, 0, 4, layer, 0, 3);
+ Cube_Overlay_Move_Pixel(layer, 0, 5, layer, 0, 4);
+ Cube_Overlay_Move_Pixel(layer, 0, 6, layer, 0, 5);
+ Cube_Overlay_Move_Pixel(layer, 0, 7, layer, 0, 6);
+ Cube_Overlay_Move_Pixel(layer, 1, 7, layer, 0, 7);
+ Cube_Overlay_Move_Pixel(layer, 2, 7, layer, 1, 7);
+ Cube_Overlay_Move_Pixel(layer, 3, 7, layer, 2, 7);
+ Cube_Overlay_Move_Pixel(layer, 4, 7, layer, 3, 7);
+ Cube_Overlay_Move_Pixel(layer, 5, 7, layer, 4, 7);
+ Cube_Overlay_Move_Pixel(layer, 6, 7, layer, 5, 7);
+ Cube_Overlay_Move_Pixel(layer, 7, 7, layer, 6, 7);
+ Cube_Overlay_Move_Pixel(layer, 7, 6, layer, 7, 7);
+ Cube_Overlay_Move_Pixel(layer, 7, 5, layer, 7, 6);
+ Cube_Overlay_Move_Pixel(layer, 7, 4, layer, 7, 5);
+ Cube_Overlay_Move_Pixel(layer, 7, 3, layer, 7, 4);
+ Cube_Overlay_Move_Pixel(layer, 7, 2, layer, 7, 3);
+ Cube_Overlay_Move_Pixel(layer, 7, 1, layer, 7, 2);
+ Cube_Overlay_Move_Pixel(layer, 7, 0, layer, 7, 1);
+ Cube_Overlay_Move_Pixel(layer, 6, 0, layer, 7, 0);
+ Cube_Overlay_Move_Pixel(layer, 5, 0, layer, 6, 0);
+ Cube_Overlay_Move_Pixel(layer, 4, 0, layer, 5, 0);
+ Cube_Overlay_Move_Pixel(layer, 3, 0, layer, 4, 0);
+ Cube_Overlay_Move_Pixel(layer, 2, 0, layer, 3, 0);
+ Cube_Overlay_Move_Pixel(layer, 1, 0, layer, 2, 0);
+ Cube_Overlay_Set_Pixel(layer, 1, 0, origin_R, origin_G, origin_B);
+ break;
+ case 1:
+ // Rotate second to outermost layer
+ Cube_Overlay_Get_Pixel(layer, 1, 1, &origin_R, &origin_G, &origin_B);
+ Cube_Overlay_Move_Pixel(layer, 1, 2, layer, 1, 1);
+ Cube_Overlay_Move_Pixel(layer, 1, 3, layer, 1, 2);
+ Cube_Overlay_Move_Pixel(layer, 1, 4, layer, 1, 3);
+ Cube_Overlay_Move_Pixel(layer, 1, 5, layer, 1, 4);
+ Cube_Overlay_Move_Pixel(layer, 1, 6, layer, 1, 5);
+ Cube_Overlay_Move_Pixel(layer, 2, 6, layer, 1, 6);
+ Cube_Overlay_Move_Pixel(layer, 3, 6, layer, 2, 6);
+ Cube_Overlay_Move_Pixel(layer, 4, 6, layer, 3, 6);
+ Cube_Overlay_Move_Pixel(layer, 5, 6, layer, 4, 6);
+ Cube_Overlay_Move_Pixel(layer, 6, 6, layer, 5, 6);
+ Cube_Overlay_Move_Pixel(layer, 6, 5, layer, 6, 6);
+ Cube_Overlay_Move_Pixel(layer, 6, 4, layer, 6, 5);
+ Cube_Overlay_Move_Pixel(layer, 6, 3, layer, 6, 4);
+ Cube_Overlay_Move_Pixel(layer, 6, 2, layer, 6, 3);
+ Cube_Overlay_Move_Pixel(layer, 6, 1, layer, 6, 2);
+ Cube_Overlay_Move_Pixel(layer, 5, 1, layer, 6, 1);
+ Cube_Overlay_Move_Pixel(layer, 4, 1, layer, 5, 1);
+ Cube_Overlay_Move_Pixel(layer, 3, 1, layer, 4, 1);
+ Cube_Overlay_Move_Pixel(layer, 2, 1, layer, 3, 1);
+ Cube_Overlay_Set_Pixel(layer, 2, 1, origin_R, origin_G, origin_B);
+ break;
+ case 2:
+ // Rotate second to innermost layer
+ Cube_Overlay_Get_Pixel(layer, 2, 2, &origin_R, &origin_G, &origin_B);
+ Cube_Overlay_Move_Pixel(layer, 2, 3, layer, 2, 2);
+ Cube_Overlay_Move_Pixel(layer, 2, 4, layer, 2, 3);
+ Cube_Overlay_Move_Pixel(layer, 2, 5, layer, 2, 4);
+ Cube_Overlay_Move_Pixel(layer, 3, 5, layer, 2, 5);
+ Cube_Overlay_Move_Pixel(layer, 4, 5, layer, 3, 5);
+ Cube_Overlay_Move_Pixel(layer, 5, 5, layer, 4, 5);
+ Cube_Overlay_Move_Pixel(layer, 5, 4, layer, 5, 5);
+ Cube_Overlay_Move_Pixel(layer, 5, 3, layer, 5, 4);
+ Cube_Overlay_Move_Pixel(layer, 5, 2, layer, 5, 3);
+ Cube_Overlay_Move_Pixel(layer, 4, 2, layer, 5, 2);
+ Cube_Overlay_Move_Pixel(layer, 3, 2, layer, 4, 2);
+ Cube_Overlay_Set_Pixel(layer, 3, 2, origin_R, origin_G, origin_B);
+ break;
+ case 3:
+ // Rotate innermost layer
+ Cube_Overlay_Get_Pixel(layer, 3, 3, &origin_R, &origin_G, &origin_B);
+ Cube_Overlay_Move_Pixel(layer, 3, 4, layer, 3, 3);
+ Cube_Overlay_Move_Pixel(layer, 4, 4, layer, 3, 4);
+ Cube_Overlay_Move_Pixel(layer, 4, 3, layer, 4, 4);
+ Cube_Overlay_Set_Pixel(layer, 4, 3, origin_R, origin_G, origin_B);
+ break;
+ }
+ } else {
+ switch(shell) {
+ case 0:
+ // Rotate outermost layer
+ Cube_Overlay_Get_Pixel(layer, 0, 0, &origin_R, &origin_G, &origin_B);
+ Cube_Overlay_Move_Pixel(layer, 1, 0, layer, 0, 0);
+ Cube_Overlay_Move_Pixel(layer, 2, 0, layer, 1, 0);
+ Cube_Overlay_Move_Pixel(layer, 3, 0, layer, 2, 0);
+ Cube_Overlay_Move_Pixel(layer, 4, 0, layer, 3, 0);
+ Cube_Overlay_Move_Pixel(layer, 5, 0, layer, 4, 0);
+ Cube_Overlay_Move_Pixel(layer, 6, 0, layer, 5, 0);
+ Cube_Overlay_Move_Pixel(layer, 7, 0, layer, 6, 0);
+ Cube_Overlay_Move_Pixel(layer, 7, 1, layer, 7, 0);
+ Cube_Overlay_Move_Pixel(layer, 7, 2, layer, 7, 1);
+ Cube_Overlay_Move_Pixel(layer, 7, 3, layer, 7, 2);
+ Cube_Overlay_Move_Pixel(layer, 7, 4, layer, 7, 3);
+ Cube_Overlay_Move_Pixel(layer, 7, 5, layer, 7, 4);
+ Cube_Overlay_Move_Pixel(layer, 7, 6, layer, 7, 5);
+ Cube_Overlay_Move_Pixel(layer, 7, 7, layer, 7, 6);
+ Cube_Overlay_Move_Pixel(layer, 6, 7, layer, 7, 7);
+ Cube_Overlay_Move_Pixel(layer, 5, 7, layer, 6, 7);
+ Cube_Overlay_Move_Pixel(layer, 4, 7, layer, 5, 7);
+ Cube_Overlay_Move_Pixel(layer, 3, 7, layer, 4, 7);
+ Cube_Overlay_Move_Pixel(layer, 2, 7, layer, 3, 7);
+ Cube_Overlay_Move_Pixel(layer, 1, 7, layer, 2, 7);
+ Cube_Overlay_Move_Pixel(layer, 0, 7, layer, 1, 7);
+ Cube_Overlay_Move_Pixel(layer, 0, 6, layer, 0, 7);
+ Cube_Overlay_Move_Pixel(layer, 0, 5, layer, 0, 6);
+ Cube_Overlay_Move_Pixel(layer, 0, 4, layer, 0, 5);
+ Cube_Overlay_Move_Pixel(layer, 0, 3, layer, 0, 4);
+ Cube_Overlay_Move_Pixel(layer, 0, 2, layer, 0, 3);
+ Cube_Overlay_Move_Pixel(layer, 0, 1, layer, 0, 2);
+ Cube_Overlay_Set_Pixel(layer, 0, 1, origin_R, origin_G, origin_B);
+ break;
+ case 1:
+ // Rotate second to outermost layer
+ Cube_Overlay_Get_Pixel(layer, 1, 1, &origin_R, &origin_G, &origin_B);
+ Cube_Overlay_Move_Pixel(layer, 2, 1, layer, 1, 1);
+ Cube_Overlay_Move_Pixel(layer, 3, 1, layer, 2, 1);
+ Cube_Overlay_Move_Pixel(layer, 4, 1, layer, 3, 1);
+ Cube_Overlay_Move_Pixel(layer, 5, 1, layer, 4, 1);
+ Cube_Overlay_Move_Pixel(layer, 6, 1, layer, 5, 1);
+ Cube_Overlay_Move_Pixel(layer, 6, 2, layer, 6, 1);
+ Cube_Overlay_Move_Pixel(layer, 6, 3, layer, 6, 2);
+ Cube_Overlay_Move_Pixel(layer, 6, 4, layer, 6, 3);
+ Cube_Overlay_Move_Pixel(layer, 6, 5, layer, 6, 4);
+ Cube_Overlay_Move_Pixel(layer, 6, 6, layer, 6, 5);
+ Cube_Overlay_Move_Pixel(layer, 5, 6, layer, 6, 6);
+ Cube_Overlay_Move_Pixel(layer, 4, 6, layer, 5, 6);
+ Cube_Overlay_Move_Pixel(layer, 3, 6, layer, 4, 6);
+ Cube_Overlay_Move_Pixel(layer, 2, 6, layer, 3, 6);
+ Cube_Overlay_Move_Pixel(layer, 1, 6, layer, 2, 6);
+ Cube_Overlay_Move_Pixel(layer, 1, 5, layer, 1, 6);
+ Cube_Overlay_Move_Pixel(layer, 1, 4, layer, 1, 5);
+ Cube_Overlay_Move_Pixel(layer, 1, 3, layer, 1, 4);
+ Cube_Overlay_Move_Pixel(layer, 1, 2, layer, 1, 3);
+ Cube_Overlay_Set_Pixel(layer, 1, 2, origin_R, origin_G, origin_B);
+ break;
+ case 2:
+ // Rotate second to innermost layer
+ Cube_Overlay_Get_Pixel(layer, 2, 2, &origin_R, &origin_G, &origin_B);
+ Cube_Overlay_Move_Pixel(layer, 3, 2, layer, 2, 2);
+ Cube_Overlay_Move_Pixel(layer, 4, 2, layer, 3, 2);
+ Cube_Overlay_Move_Pixel(layer, 5, 2, layer, 4, 2);
+ Cube_Overlay_Move_Pixel(layer, 5, 3, layer, 5, 2);
+ Cube_Overlay_Move_Pixel(layer, 5, 4, layer, 5, 3);
+ Cube_Overlay_Move_Pixel(layer, 5, 5, layer, 5, 4);
+ Cube_Overlay_Move_Pixel(layer, 4, 5, layer, 5, 5);
+ Cube_Overlay_Move_Pixel(layer, 3, 5, layer, 4, 5);
+ Cube_Overlay_Move_Pixel(layer, 2, 5, layer, 3, 5);
+ Cube_Overlay_Move_Pixel(layer, 2, 4, layer, 2, 5);
+ Cube_Overlay_Move_Pixel(layer, 2, 3, layer, 2, 4);
+ Cube_Overlay_Set_Pixel(layer, 2, 3, origin_R, origin_G, origin_B);
+ break;
+ case 3:
+ // Rotate innermost layer
+ Cube_Overlay_Get_Pixel(layer, 3, 3, &origin_R, &origin_G, &origin_B);
+ Cube_Overlay_Move_Pixel(layer, 4, 3, layer, 3, 3);
+ Cube_Overlay_Move_Pixel(layer, 4, 4, layer, 4, 3);
+ Cube_Overlay_Move_Pixel(layer, 3, 4, layer, 4, 4);
+ Cube_Overlay_Set_Pixel(layer, 3, 4, origin_R, origin_G, origin_B);
+ break;
+ }
+ }
+ }
+}
+
+////////////////////////////
+// Text control functions //
+////////////////////////////
+
+void Cube_Text_Init(uint8_t *string, uint8_t length, uint16_t R, uint16_t G, uint16_t B) {
+ // Ensure that the length of the string does not exceed the storage buffer
+ if (length > CUBE_STRING_MAX_LENGTH) length = CUBE_STRING_MAX_LENGTH;
+
+ Cube_Overlay_Clear();
+
+ // Copy the passed data into the buffer
+ uint8_t i;
+ for (i = 0; i < length; i++)
+ cube_data_ptr->string[i] = string[i];
+ cube_data_ptr->string_length = length;
+ cube_data_ptr->string_index = 0;
+ cube_data_ptr->string_line = 0;
+ cube_data_ptr->string_R = R;
+ cube_data_ptr->string_G = G;
+ cube_data_ptr->string_B = B;
+}
+
+void Cube_Text_Update(void) {
+ uint8_t layer;
+ uint16_t line;
+
+ // Rotate before drawing the new line at (0,0)
+ Cube_Overlay_Rotate_Shell(0, 0);
+
+ // Get the next vertical line of the character currently being drawn
+ if (cube_data_ptr->string_line == 5) {
+ line = 0x0; // Leave a space between characters
+ } else {
+ line = font[(cube_data_ptr->string[cube_data_ptr->string_index] * 5)
+ + cube_data_ptr->string_line];
+ }
+
+ // Draw the line onto (0,0) using the specified color
+ for (layer = 8; layer != 0; layer--) {
+ if (line & 0x1) {
+ Cube_Overlay_Set_Pixel(layer-1, 0, 0, cube_data_ptr->string_R,
+ cube_data_ptr->string_G, cube_data_ptr->string_B);
+ } else {
+ Cube_Overlay_Set_Pixel(layer-1, 0, 0, 0x00, 0x00, 0x00);
+ }
+ line >>= 1;
+ }
+
+ // Increment the vertical line and the character as needed
+ if (cube_data_ptr->string_line == 5) {
+ cube_data_ptr->string_line = 0;
+ if (cube_data_ptr->string_index == cube_data_ptr->string_length-1) {
+ cube_data_ptr->string_index = 0;
+ } else {
+ cube_data_ptr->string_index += 1;
+ }
+ } else {
+ cube_data_ptr->string_line += 1;
+ }
+}
+
+void Cube_Text_Insert(uint8_t c, uint16_t R, uint16_t G, uint16_t B, uint16_t delay) {
+ // Save the character to insert
+ cube_data_ptr->string[0] = c;
+ cube_data_ptr->string_length = 1;
+ cube_data_ptr->string_line = 0;
+ cube_data_ptr->string_R = R;
+ cube_data_ptr->string_G = G;
+ cube_data_ptr->string_B = B;
+
+ if (delay == 0) {
+ int i;
+ for (i = 0; i < 6; i++) {
+ Cube_Text_Single_Char_Interupt();
+ }
+ } else {
+ // Start a timer to update the overlay with the inserted character
+ TIMER4_Stop();
+ TIMER4_Init(NULL, NULL, &Cube_Text_Single_Char_Interupt, delay);
+ TIMER4_Start();
+ }
+}
+
+void Cube_Text_Single_Char_Interupt(void) {
+ uint8_t layer;
+ uint8_t line;
+
+ // Rotate before drawing the new line at (0,0)
+ Cube_Overlay_Rotate_Shell(0, 0);
+
+ // Get the next vertical line of the character currently being drawn
+ if (cube_data_ptr->string_line == 0) {
+ line = 0x0; // Leave a space between characters
+ } else {
+ line = font[(cube_data_ptr->string[0] * 5) + cube_data_ptr->string_line - 1];
+ }
+
+ // Draw the line onto (0,0) using the specified color
+ for (layer = 8; layer != 0; layer--) {
+ if (line & 0x1) {
+ Cube_Overlay_Set_Pixel(layer-1, 0, 0, cube_data_ptr->string_R,
+ cube_data_ptr->string_G, cube_data_ptr->string_B);
+ } else {
+ Cube_Overlay_Set_Pixel(layer-1, 0, 0, 0x00, 0x00, 0x00);
+ }
+ line >>= 1;
+ }
+
+ // Increment the vertical line or stop the timer as needed
+ if (cube_data_ptr->string_line == 5) {
+ TIMER4_Stop();
+ } else {
+ cube_data_ptr->string_line += 1;
+ }
+}
+
+void Cube_Text_Interrupt(void) {
+ Cube_Text_Update();
+}
+
+/////////////////////////////////////////////
+// Functions for processing streaming data //
+/////////////////////////////////////////////
+
+void Cube_Data_In(uint8_t c) {
+ // Reset upon receiving the start int8_t
+ if (c == CUBE_START_CHAR) {
+ cube_data_ptr->frame_length = 0;
+ cube_data_ptr->frame_index = 0;
+ cube_data_ptr->frame_checksum = 0;
+ cube_data_ptr->frame_command = 0;
+ cube_data_ptr->frame_escape = 0;
+ cube_data_ptr->frame_state = READ_LENGTH_MSB;
+ return;
+ }
+ // If the input is the escape int8_t, XOR the next int8_t received
+ if (c == CUBE_ESCAPE_CHAR) {
+ cube_data_ptr->frame_escape = 1;
+ return;
+ }
+ // XOR the input int8_t if needed
+ if (cube_data_ptr->frame_escape) {
+ c ^= CUBE_ESCAPE_XOR;
+ cube_data_ptr->frame_escape = 0;
+ }
+ // Process data
+ switch (cube_data_ptr->frame_state) {
+ case IDLE:
+ // Reflect the character back to the transmitter
+ UART1_Write(&c, 1);
+ break;
+ case READ_LENGTH_MSB: // Save MSB of length
+ cube_data_ptr->frame_length |= (c << 8);
+ cube_data_ptr->frame_state = READ_LENGTH_LSB;
+ break;
+ case READ_LENGTH_LSB: // Save LSB of length
+ cube_data_ptr->frame_length |= c;
+ cube_data_ptr->frame_state = READ_COMMAND;
+ break;
+ case READ_COMMAND: // Store the command byte
+ cube_data_ptr->frame_checksum += c;
+ cube_data_ptr->frame_command = c;
+ if (cube_data_ptr->frame_length == 1)
+ cube_data_ptr->frame_state = READ_CHECKSUM;
+ else
+ cube_data_ptr->frame_state = READ_DATA;
+ break;
+ case READ_DATA: // Read the passed data into the buffer
+ cube_data_ptr->frame_checksum += c;
+ cube_data_ptr->frame_buffer[cube_data_ptr->frame_index] = c;
+ cube_data_ptr->frame_index++;
+ if (cube_data_ptr->frame_index == cube_data_ptr->frame_length - 1)
+ cube_data_ptr->frame_state = READ_CHECKSUM;
+ break;
+ case READ_CHECKSUM: // Process frame if checksum is valid
+ cube_data_ptr->frame_checksum = 0xFF - cube_data_ptr->frame_checksum;
+ if (cube_data_ptr->frame_checksum == c) {
+ Cube_Data_In_Process_Frame();
+ }
+ cube_data_ptr->frame_state = IDLE;
+ cube_data_ptr->frame_index = 0;
+ cube_data_ptr->frame_length = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void Cube_Data_In_Process_Frame(void) {
+ // Here we process received frames depending on the command
+ uint8_t *frame = cube_data_ptr->frame_buffer;
+ switch (cube_data_ptr->frame_command) {
+ case CUBE_COMMAND_SET_BC:
+ TIMER5_Stop();
+ Delay_MS(1); // Need to wait for all SPI writes to complete
+ Cube_Write_DCS(frame[0]);
+ TIMER5_Start();
+ break;
+ case CUBE_COMMAND_CLEAR:
+ Cube_Clear();
+ break;
+ case CUBE_COMMAND_SET_PIXEL:
+ Cube_Set_Pixel(frame[0], frame[1], frame[2], frame[3], frame[4], frame[5]);
+ break;
+ case CUBE_COMMAND_SET_ALL:
+ Cube_Data_Direct_Write_All(&frame[0]);
+ break;
+ case CUBE_COMMAND_START_TEXT:
+ Cube_Text_Init(&frame[3], cube_data_ptr->frame_length - 4, frame[0], frame[1], frame[2]);
+ TIMER4_Start();
+ break;
+ case CUBE_COMMAND_STOP_TEXT:
+ TIMER4_Stop();
+ Cube_Overlay_Clear();
+ break;
+ default:
+ break;
+ }
+}
+
+void Cube_Data_Direct_Write_All(uint8_t *buffer) {
+ memcpy(cube_data_ptr->GCS, buffer, CUBE_LAYER_COUNT * GCS_LAYER_SIZE);
+}
+
+void Cube_Ethernet_Frame_In(void) {
+ uint8_t i,j,k;
+ uint8_t buffer[2048] = {0};
+ uint16_t length;
+
+ // Read and process the ethernet packet
+ if (!ETH_Read_Packet(buffer, &length)) {
+ // Check the opcode (first byte) to determine what to do
+ if (buffer[0] == CUBE_ETH_RESET) { // 0x1 - Reset into Ethernet mode
+ Reset_Board(BOARD_MODE_ETHERNET);
+ } else if (Get_Board_State() == BOARD_MODE_ETHERNET) {
+ ClearWDT();
+ if (buffer[0] == CUBE_EHT_IDLE) { // 0x2 - Reset back to idle mode
+ Reset_Board(BOARD_MODE_IDLE);
+ } else if (buffer[0] == CUBE_ETH_CLEAR) { // 0xA
+ Cube_Clear();
+ } else if (buffer[0] == CUBE_ETH_DCS) { // 0xB
+ // Byte 1 = global brightness value
+ Cube_Write_DCS(buffer[1]);
+ } else if (buffer[0] == CUBE_ETH_ROTATE) { // 0xC
+ // Byte 1 = directon to rotate
+ Cube_Rotate(buffer[1]);
+ } else if (buffer[0] == CUBE_ETH_ROTATE_LAYER) { // 0xD
+ // Byte 1 = layer to rotate
+ // Byte 2 = direction to rotate
+ Cube_Rotate_Shell(buffer[1], buffer[2]);
+ } else if (buffer[0] == CUBE_ETH_WRITE_ALL) { // 0x10
+ // Byte 1+ = pixel color data (R/G/B)
+ if (length == 0x0601) {
+ uint16_t index = 1;
+ for (i = 0; i < CUBE_LAYER_COUNT; i++) {
+ for (j = 0; j < CUBE_COLUMN_COUNT; j++) {
+ for (k = 0; k < CUBE_ROW_COUNT; k++) {
+ Cube_Set_Pixel(i, k, j, buffer[index], buffer[index+1], buffer[index+2]);
+ index = index + 3;
+ }
+ }
+ }
+ }
+ } else if (buffer[0] == CUBE_ETH_WRITE_PIXEL) { // 0x11
+ // Byte 1 = row index
+ // Byte 2 = column index
+ // Byte 3 = layer index
+ // Byte 4 = red channel
+ // Byte 5 = green channel
+ // Byte 6 = blue channel
+ Cube_Set_Pixel(buffer[3], buffer[1], buffer[2], buffer[4], buffer[5], buffer[6]);
+ } else if (buffer[0] == CUBE_ETH_WRITE_CHANNEL) { // 0x12
+ // Byte 1 = color channel, 0 = red, 1 = green, 2 = blue
+ // Byte 2+ = color data
+ uint16_t r, g, b;
+ uint16_t index = 2;
+ if (buffer[1] % 3 == 0) {
+ for (i = 0; i < CUBE_LAYER_COUNT; i++) {
+ for (j = 0; j < CUBE_ROW_COUNT; j++) {
+ for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
+// Cube_Get_Pixel(i, j, k, &r, &g, &b);
+ Cube_Set_Pixel(i, j, k, buffer[index], 0x00, 0x00);
+ index++;
+ }
+ }
+ }
+ } else if (buffer[1] % 3 == 1) {
+ for (i = 0; i < CUBE_LAYER_COUNT; i++) {
+ for (j = 0; j < CUBE_ROW_COUNT; j++) {
+ for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
+ Cube_Get_Pixel(i, j, k, &r, &g, &b);
+ Cube_Set_Pixel(i, j, k, r, buffer[index], b);
+ index++;
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < CUBE_LAYER_COUNT; i++) {
+ for (j = 0; j < CUBE_ROW_COUNT; j++) {
+ for (k = 0; k < CUBE_COLUMN_COUNT; k++) {
+ Cube_Get_Pixel(i, j, k, &r, &g, &b);
+ Cube_Set_Pixel(i, j, k, r, g, buffer[index]);
+ index++;
+ }
+ }
+ }
+ }
+ } else if (buffer[0] == CUBE_ETH_WRITE_TEXT_SCROLL) { // 0x20
+ // Byte 1 = length of string
+ // Byte 2 = red channel
+ // Byte 3 = green channel
+ // Byte 4 = blue channel
+ // Byte 5 = update speed (ms)
+ // Byte 6+ = text string
+ if (buffer[1] != 0) {
+ TIMER4_Stop();
+ Cube_Text_Init(&buffer[6], buffer[1], buffer[2], buffer[3], buffer[4]);
+ TIMER4_Init(NULL, NULL, &Cube_Text_Interrupt, buffer[5]);
+ TIMER4_Start();
+ } else {
+ TIMER4_Stop();
+ Cube_Overlay_Clear();
+ }
+ } else if (buffer[0] == CUBE_ETH_WRITE_TEXT_STATIC) { // 0x21
+ // Byte 1 = length of string
+ // Byte 2 = red channel
+ // Byte 3 = green channel
+ // Byte 4 = blue channel
+ // Byte 5+ = text string
+ if (buffer[1] != 0) {
+ TIMER4_Stop();
+ Cube_Text_Init(&buffer[5], buffer[1], buffer[2], buffer[3], buffer[4]);
+ for (i = 0; i < buffer[1] * 5; i++) {
+ Cube_Text_Update();
+ }
+ } else {
+ TIMER4_Stop();
+ Cube_Overlay_Clear();
+ }
+ } else if (buffer[0] == CUBE_EHT_WRITE_TEXT_INSERT) { // 0x22
+ // Byte 1 = red channel
+ // Byte 2 = green channel
+ // Byte 3 = blue channel
+ // Byte 4 = delay x6 between shifts
+ // Byte 5 = character
+ TIMER4_Stop();
+ Cube_Text_Insert(buffer[5], buffer[1], buffer[2], buffer[3], buffer[4]);
+ } else if (buffer[0] == CUBE_ETH_WATERFALL) { // 0x30
+ // Byte 1 = height of column 0
+ // Byte 2 = height of column 1
+ // Byte 3 = height of column 2
+ // Byte 4 = height of column 3
+ // Byte 5 = height of column 4
+ // Byte 6 = height of column 5
+ // Byte 7 = height of column 6
+ // Byte 8 = height of column 7
+ Cube_Shift_Waterfall(&buffer[1]);
+ } else if (buffer[0] == CUBE_ETH_SPHERE) { // 0x31
+ // Byte 1 = layer (0 = innermost)
+ // Byte 2 = red channel
+ // Byte 3 = green channel
+ // Byte 4 = blue channel
+ Cube_Set_Sphere(buffer[1], buffer[2], buffer[3], buffer[4]);
+ }
+ }
+ }
+}
/PIC Stuff/Cerebot_32MX7_LED_Cube/CUBE.h
0,0 → 1,164
#ifndef CUBE_H
#define CUBE_H
 
// Cube Parameters
#define CUBE_ROW_COUNT 8
#define CUBE_COLUMN_COUNT 8
#define CUBE_LAYER_COUNT 8
#define CUBE_PIXELS 512
#define CUBE_ROTATIONS 7
 
#define GCS_REG_SIZE 36
#define GCS_LAYER_SIZE (GCS_REG_SIZE*CUBE_ROW_COUNT)
 
// Color Definitions
#define CLEAR 0x000,0x000,0x000
#define RED 0x0FF,0x000,0x000
#define ORANGE 0x0FF,0x040,0x000
#define YELLOW 0x0FF,0x0FF,0x000
#define GREEN 0x000,0x0FF,0x000
#define TEAL 0x000,0x0FF,0x040
#define BLUE 0x000,0x000,0x0FF
#define PURPLE 0x0FF,0x000,0x0FF
#define WHITE 0x0FF,0x0FF,0x0FF
 
// Control Pin Declarations
#define DCSIN_TRIS TRISDbits.TRISD3
#define DCSCK_TRIS TRISDbits.TRISD12
 
#define DCSIN LATDbits.LATD3
#define DCSCK LATDbits.LATD12
 
#define SFT_R_TRIS TRISBbits.TRISB15
#define SFT_K_TRIS TRISDbits.TRISD5
#define SFT_S_TRIS TRISDbits.TRISD4
#define SFT_D_TRIS TRISBbits.TRISB14
 
#define SFT_R LATBbits.LATB15
#define SFT_K LATDbits.LATD5
#define SFT_S LATDbits.LATD4
#define SFT_D LATBbits.LATB14
 
#define GSLAT_TRIS TRISDbits.TRISD9
#define XBLNK_TRIS TRISDbits.TRISD2
 
#define GSLAT LATDbits.LATD9
#define XBLNK LATDbits.LATD2
 
// String Overlay Buffer Size
#define CUBE_STRING_MAX_LENGTH 255
 
// Data Streaming In Buffer Size
#define CUBE_FRAME_BUFFER_SIZE 3000
#define CUBE_START_CHAR 0x7E
#define CUBE_ESCAPE_CHAR 0x7D
#define CUBE_ESCAPE_XOR 0x20
 
// Data Streaming In Command Set
#define CUBE_COMMAND_SET_BC 0x0A // [Brightness Value]
#define CUBE_COMMAND_CLEAR 0x0B // (no data)
#define CUBE_COMMAND_SET_PIXEL 0x10 // [Layer, Row, Column, R, G, B]
#define CUBE_COMMAND_SET_ALL 0x11 // [R1, G1, B1, R2, ...]
#define CUBE_COMMAND_START_TEXT 0x20 // [R, G, B, Char1, Char2, Char3, ...]
#define CUBE_COMMAND_STOP_TEXT 0x21 // (no data)
 
// Ethernet Op-Codes
#define CUBE_ETH_RESET 0x01
#define CUBE_EHT_IDLE 0x02
#define CUBE_ETH_CLEAR 0x0A
#define CUBE_ETH_DCS 0x0B
#define CUBE_ETH_ROTATE 0x0C
#define CUBE_ETH_ROTATE_LAYER 0x0D
#define CUBE_ETH_WRITE_ALL 0x10
#define CUBE_ETH_WRITE_PIXEL 0x11
#define CUBE_ETH_WRITE_CHANNEL 0x12
#define CUBE_ETH_WRITE_TEXT_SCROLL 0x20
#define CUBE_ETH_WRITE_TEXT_STATIC 0x21
#define CUBE_EHT_WRITE_TEXT_INSERT 0x22
#define CUBE_ETH_WATERFALL 0x30
#define CUBE_ETH_SPHERE 0x31
 
typedef enum {
IDLE,
READ_LENGTH_MSB,
READ_LENGTH_LSB,
READ_COMMAND,
READ_DATA,
READ_CHECKSUM
} PROCESS_STATE;
 
typedef struct {
// Variables for base cube
uint8_t GCS[CUBE_LAYER_COUNT][GCS_LAYER_SIZE];
uint8_t GCS_OVERLAY[CUBE_LAYER_COUNT][GCS_LAYER_SIZE];
uint8_t GCS_WRITE[CUBE_LAYER_COUNT][GCS_LAYER_SIZE];
uint8_t current_layer;
uint8_t rotation_counter;
 
// Variables for the scrolling text
uint8_t string[CUBE_STRING_MAX_LENGTH];
uint8_t string_length;
uint8_t string_index;
uint8_t string_line;
uint16_t string_R, string_G, string_B;
 
// Variables for input frame data
PROCESS_STATE frame_state;
uint8_t frame_buffer[CUBE_FRAME_BUFFER_SIZE];
uint8_t frame_checksum;
uint32_t frame_length;
uint32_t frame_index;
uint32_t frame_command;
uint32_t frame_escape;
} CUBE_DATA;
 
void Cube_Init(CUBE_DATA *data, uint8_t BC);
void Cube_Timer_Interrupt(void);
 
// Callbacks on completion of DCS/GCS writes
void Cube_DCS_Write_Callback(void);
void Cube_GCS_Write_Callback(void);
 
// Cube control functions
void Cube_Write_DCS(uint8_t BC);
void Cube_Clear(void);
void Cube_Set_All(uint16_t R, uint16_t G, uint16_t B);
void Cube_Set_Layer(uint8_t layer, uint16_t R, uint16_t G, uint16_t B);
void Cube_Set_Row(uint8_t row, uint16_t R, uint16_t G, uint16_t B);
void Cube_Set_Column(uint8_t column, uint16_t R, uint16_t G, uint16_t B);
void Cube_Set_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t R, uint16_t G, uint16_t B);
void Cube_Get_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t* R, uint16_t* G, uint16_t* B);
void Cube_Move_Pixel(uint8_t layer1, uint8_t row1, uint8_t column1, uint8_t layer2, uint8_t row2, uint8_t column2);
void Cube_Set_Sphere(uint8_t layer, uint8_t R, uint8_t G, uint8_t B);
void Cube_Set_Shell(uint8_t layer, uint8_t R, uint8_t G, uint8_t B);
void Cube_Rotate_Shell(uint8_t shell, uint8_t direction);
void Cube_Rotate(uint8_t direction);
void Cube_Shift_Row(uint8_t direction);
 
void Cube_Shift_Waterfall(uint8_t *values);
void Cube_Shift_Waterfall2(uint8_t *values);
 
// Overlay control functions
void Cube_Overlay_Clear(void);
void Cube_Overlay_Set_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t R, uint16_t G, uint16_t B);
void Cube_Overlay_Get_Pixel(uint8_t layer, uint8_t row, uint8_t column, uint16_t* R, uint16_t* G, uint16_t* B);
void Cube_Overlay_Move_Pixel(uint8_t layer1, uint8_t row1, uint8_t column1, uint8_t layer2, uint8_t row2, uint8_t column2);
void Cube_Overlay_Rotate_Shell(uint8_t shell, uint8_t direction);
 
// Text control functions
void Cube_Text_Init(uint8_t *string, uint8_t length, uint16_t R, uint16_t G, uint16_t B);
void Cube_Text_Update(void);
void Cube_Text_Insert(uint8_t c, uint16_t R, uint16_t G, uint16_t B, uint16_t delay);
void Cube_Text_Single_Char_Interupt(void);
void Cube_Text_Interrupt(void);
 
// Data stream in control functions
// UART functions
void Cube_Data_In(uint8_t c);
void Cube_Data_In_Process_Frame(void);
void Cube_Data_Direct_Write_All(uint8_t *buffer);
// Ethernet functions
void Cube_Ethernet_Frame_In(void);
 
#endif /* CUBE_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/README.txt
0,0 → 1,209
Here lies some random pieces of information that may make it easier to understand the code base
 
Notes:
Power supply must be 5V for proper operation of the board!
 
KNOWN ISSUES:
Cube is occasionally flickering to ~60Hz. Need to figure out why.
Interrupts dont seem to be preempting properly. Not sure why.
 
PERIPHERAL USAGE:
SPI1 - Used by the cube code to send data to the ube
SPI4 - Unused
I2C1 - Used by the controller code
TIMER2 - Used by PWM2
TIMER4 - Used by the cube code for the overlay rotation interrupt
TIMER5 - Used by the cube code for the update layer interrupt
UART1 - Used by the cube code for reading in frame data
PWM2 - Generates a constant ~20MHz output, uses TIMER2
ETHERNET - Used to remote-update the cube
 
PERIPHERAL INTERRUPT PRIORITY LEVELS:
IPL1 = lowest, IPL7 = highest priority
SPI1 - Priority 5, Subpriority 1
SPI4 - Priority 6, Subpriority 2
I2C1 - Priority 5, Subpriority 1
TIMER5 - Priority 3, Subpriority 1
TIMER4 - Priority 1, Subpriority 1
UART1 - Priority 2, Subpriority 1
ETHERNET - Priority 1, Subpriority 1
 
 
PIN I/Os:
 
JA-01 AN2/C2IN-/CN4/RB2 RB02
JA-02 AN3/C2IN+/CN5/RB3 RB03
JA-03 AN4/C1IN-/CN6/RB4 RB04
JA-04 PGEC2/AN6/OCFA/RB6 RB06
JA-07 PGED2/AN7/RB7 RB07
JA-08 AN8/C1OUT/RB8 RB08
JA-09 AN9/C2OUT/RB9 RB09
JA-10 CVrefout/PMA13/AN10/RB10 RB10
*
JB-01 PMD0/RE0 RE00
JB-02 PMD1/RE1 RE01
JB-03 PMD2/RE2 RE02
JB-04 PMD3/RE3 RE03
JB-07 PMD4/RE4 RE04
JB-08 PMD5/RE5 RE05
JB-09 PMD6/RE6 RE06
JB-10 PMD7/RE7 RE07
*
JC-01 T2CK/RC1 RC01
JC-02 C2RX/PMD8/RG0 RG00
JC-03 C2TX/ETXERR/PMD9/RG1 RG01
JC-04 ETXCLK/PMD15/CN16/RD7 RD07
JC-07 AN15/ERXD3/AETXD2/OCFB/PMALL/PMA0/CN12/RB15 RB15 (SFT_R)
JC-08 PMRD/CN14/RD5 RD05 (SFT_K)
JC-09 OC5/PMWR/CN13/RD4 RD04 (SFT_S)
JC-10 AN14/ERXD2/AETXD3/PMALH/PMA1/RB14 RB14 (SFT_D)
*
JD-01 SS1/IC2/RD9 RD09 (GSLAT)
JD-02 SDO1/OC1/INT0/RD0 RD00 (GSSIN)
JD-03 T5CK/SDI1/RC4 RC04 (GSSOUT)
JD-04 SCK1/IC3/PMCS2/PMA15/RD10 RD10 (GSSCK)
JD-07 OC2/RD1 RD01 (PWMCK)
JD-08 OC3/RD2 RD02 (XBLNK)
JD-09 OC4/RD3 RD03 (DCSIN)
JD-10 ETXD2/IC5/PMD12/RD12 RD12 (DCSCK)
*
JE-01 AETXD0/SS3/U4RX/U1CTS/CN20/RD14 RD14
JE-02 SCL3/SDO3/U1TX/RF8 RF08
JE-03 SDA3/SDI3/U1RX/RF2 RF02
JE-04 AETXD1/SCK3/U4TX/U1RTS/CN21/RD15 RD15
JE-07 TRCLK/RA6 RA06 on 32MX7 or INT1/RF8 on MX7CK
JE-08 TRD3/RA7 RA07
JE-09 Vref-/CVref-/AERXD2/PMA7/RA9 RA09
JE-10 Vref+/CVref+/AERXD3/PMA6/RA10 RA10
*
JF-01 AC1RX/SS4/U5RX/U2CTS/RF12 RF12 shared with CAN1 Transceiver (JP-1)
JF-02 SCL5/SDO4/U2TX/PMA8/CN18/RF5 RF05
JF-03 SDA5/SDI4/U2RX/PMA9/CN17/RF4 RF04
JF-04 AC1TX/SCK4/U5TX/U2RTS/RF13 RF13 shared with CAN1 Transceiver (JP-2)
JF-07 TMS/RA0 RA00 on 32MX7 or INT2/RF9 on MX7CK
JF-08 TCK/RA1 RA01
JF-09 TDI/RA4 RA04
JF-10 TDO/RA5 RA05
 
N/A SCL2/RA2 RA02 I2C bus #2, not shared with Pmod connector
N/A SDA2/RA3 RA03 I2C bus #2, not shared with Pmod connector
N/A AETXCLK/SCL1/INT3/RA14 RA14 I2C Bus #1, not shared with Pmod connector
N/A AETXEN/SDA1/INT4/RA15 RA15 I2C Bus #1, not shared with Pmod connector
N/A PGED1/AN0/CN2/RB0 RB00 Used by debug circuit, PGC
N/A PGEC1/AN1/CN3/RB1 RB01 Used by debug circuit, PGD
N/A AN5/C1IN+/VBUSON/CN7/RB5 RB05 USB VBUSON
N/A AN11/ERXERR/AETXERR/PMA12/RB11 RB11 Ethernet PHY
N/A AN12/ERXD0/AECRS/PMA11/RB12 RB12 Ethernet PHY
N/A AN13/ERXD1/AECOL/PMA10/RB13 RB13 Ethernet PHY
N/A OSC1/CLKI/RC12 RC12 Primary Oscillator Crystal
N/A SOSCI/CN1/RC13 RC13 Secondary Oscillator Crystal
N/A SOSCO/T1CK/CN0/RC14 RC14 Secondary Oscillator Crystal
N/A OSC2/CLKO/RC15 RC15 Primary Oscillator Crystal
N/A ETXEN/PMD14/CN15/RD6 RD06 Ethernet PHY
N/A RTCC/EMDIO/AEMDIO/IC1/RD8 RD08 Ethernet PHY
N/A EMDC/AEMDC/IC4/PMCS1/PMA14/RD11 RD11 Ethernet PHY
N/A ETXD3/PMD13/CN19/RD13 RD13 BTN3
N/A AERXD0/INT1/RE8 RE08 USB Overcurrent detect
N/A AERXD1/INT2/RE9 RE09 Ethernet PHY Reset
N/A C1RX/ETXD1/PMD11/RF0 RF00 Ethernet PHY
N/A C1TX/ETXD0/PMD10/RF1 RF01 Ethernet PHY
N/A USBID/RF3 RF03 USBID (USB-4)
N/A D+/RG2 RG02 D+ (USB-3)
N/A D-/RG3 RG03 D- (USB-2)
N/A ECOL/SCK2/U6TX/U3RTS/PMA5/CN8/RG6 RG06 BTN1
N/A ECRS/SDA4/SDI2/U3RX/PMA4/CN9/RG7 RG07 BTN2
N/A ERXDV/AERXDV/ECRSDV/AECRSDV/SCL4/SDO2/U3TX/PMA3/CN10/RG8 RG08 Ethernet PHY
N/A ERXCLK/AERXCLK/EREFCLK/AEREFCLK/SS2/U6RX/U3CTS/PMA2/CN11/RG9 RG09 Ethernet PHY
N/A TRD1/RG12 RG12 LED1
N/A TRD0/RG13 RG13 LED2
N/A TRD2/RG14 RG14 LED3
N/A AERXERR/RG15 RG15 LED4
 
 
CONNECTORS:
 
J1 - Serial USB Misc Connections (MX7CK only)
* This header contains other FTDI UART function pins (CTS, DSR, DCD, RI)
J2 - Serial USB Connector (MX7CK only)
* This connector is connected to UART1 or PMOD JE
J7 - I2C port daisy chain connector
* On the Cerebot 32MX7, this connector provides access to the I2C signals, power and ground for I2C2.
* On the Cerebot MX7CK, this connector provides access to the I2C signals, power and ground for I2C1 + INT3/4.
J8 - I2C port daisy chain connector
* On the Cerebot 32MX7, this connector provides access to the I2C signals, power and ground for I2C1.
* On the Cerebot MX7CK, this connector provides access to the I2C signals, power and ground for I2C2.
EEPROM is changed to this port on the MX7CK
J9 - CAN #1 Connector
* This connector is used to access the signals for CAN #1.
J10 - CAN #2 Connector
* This connector is used to access the signals for CAN #2.
J11 - Ethernet Connector
* This connector provides access to the 10/100 Ethernet port.
J12-J14
* Do Not Use.
J15 - Debug USB Connector
* This connector is used to connect the on-board programming and
debug circuit to the PC for use with the MPLAB IDE.
J16 - Power supply source select
* This jumper is used to select the source of main board power.
Place a shorting block in the upper, ?USB? position to have the
board powered from the USB device connector, J19.
Place a shorting block in the center, ?EXT? position to have the
board powered from one of the external power connectors, J17 or J18.
Place a shorting block in the lower, ?DBG? position to have the
board powered from the debug USB connector, J15.
J17 - External Power Connector
* This is a 2.5mm x 5.5mm, center positive, coax power connector used to
provide external power to the board. The optional Digilent 5V Switching
Power Supply is connected here.
J18 - External Power Connector
* This is a screw terminal connector used to provide external power to
the board. Be sure to observe proper polarity (marked near the connector)
when providing power via this connector, or damage to the board and/or
connected devices may result.
J19 - USB Device / OTG Connector
* This is a USB micro-AB connector. It is used when using the PIC32MX795
microcontroller to implement a USB device or OTG Host/Device.
J20 - USB Host Connector
* This is a standard sized USB type A connector. This connector is used to
connect USB devices to the board when using the PIC32MX795 microcontroller
to implement an embedded USB host.
 
JUMPERS:
 
JP1 & JP2 - CAN or Pmod Select
* These jumpers select microcontroller signals RF12 and RF13 for use with CAN
#1 or Pmod connector JF. Place these jumpers in the CAN position to use CAN
#1. Place the jumpers in the PMOD position to use then with Pmod connector JF.
JP3 & JP4 - Pull-up enable for I2C port #2
* These two jumpers are used to enable/disable the pull-up resistors on I2C
port #2. Insert shorting blocks on these two jumpers to enable the pull-up
resistors. Remove the shorting blocks to disable the pull-up resistors. Only
a single device on the I2C bus should have the pull-up resistors enabled.
JP5 - CAN #1 Termination
* This jumper is used to enable/disable the 120 ohm termination resistor for
CAN #1. Insert the shorting block to enable the termination resistor, remove
it to disable the termination resistor.
JP6 - CAN #1 5V0 Enable
* This jumper is used to enable/disable providing 5V to the CAN #1 connector.
Insert the shorting block to connect the board 5V0 supply to pins 9 & 10 of
CAN #1 connector. Remove the shorting block to disconnect the 5V0 supply.
JP7 - CAN #2 Termination
* This jumper is used to enable/disable the 120 ohm termination resistor for
CAN #2. Insert the shorting block to enable the termination resistor, remove
it to disable the termination resistor.
JP8 - CAN #1 5V0 Enable
* This jumper is used to enable/disable providing 5V to the CAN #1 connector.
Insert the shorting block to connect the board 5V0 supply to pins 9 & 10 of
CAN #1 connector. Remove the shorting block to disconnect the 5V0 supply.
JP9 - Do Not Use
JP10 - USB Host Power Select
* This jumper is used to select which host connector is powered when host power
is enabled. Place the shorting block in the ?MICRO? position to supply power
to the USB micro-AB OTG Connector, J19. Place the shorting block in the ?A?
position to supply power to the USB type A Host Connector, J20.
JP11 - Programmer Serial Select (MX7CK only)
* Remove the jumper to disconnect the USB serial converter's connection to the
MCLR pin. Disconnecting this when using the built in debugger is recommended.
JP17 - Do Not Use
/PIC Stuff/Cerebot_32MX7_LED_Cube/ETHERNET.c
0,0 → 1,356
#include "defines.h"
#include "ETHERNET.h"
 
static ETH_DATA *eth_data;
 
/* Function to convert from virtual address to physical address
See 3.4.1 in reference manual for explanation */
uint32_t VA_TO_PA(uint32_t ptr) {
uint32_t ret = ptr & 0x1FFFFFFF;
return ret;
}
 
void ETH_Init(ETH_DATA *data, void(*tx_callback)(void), void(*rx_callback)(void)) {
// Save a pointer to the descriptor tables
eth_data = data;
eth_data->tx_callback = tx_callback;
eth_data->rx_callback = rx_callback;
 
// Bring the PHY reset line high to initialize the PHY
PHY_RESET_TRIS = 0;
PHY_RESET_LAT = 0;
Delay_US(100);
PHY_RESET_LAT = 1;
 
INTDisableInterrupts();
 
// Initialize the I/O lines (dont actually need this)
ETH_MDC_TRIS = 0;
ETH_MDIO_TRIS = 1;
ETH_TXEN_TRIS = 0;
ETH_TXD0_TRIS = 0;
ETH_TXD1_TRIS = 0;
ETH_RXCLK_TRIS = 1;
ETH_RXDV_TRIS = 1;
ETH_RXD0_TRIS = 1;
ETH_RXD1_TRIS = 1;
ETH_RXERR_TRIS = 1;
 
eth_data->TX_descriptor_index = 0;
eth_data->RX_descriptor_index = 0;
 
// Initialize values in the descriptor tables
uint8_t i;
for (i = 0; i < ETH_TX_DESCRIPTOR_COUNT; i++) {
// Set the NPV values for each descriptor (linear list)
eth_data->TX_ED_table.descriptor[i].NPV = 0;
// Set the EOWN values for each descriptor
eth_data->TX_ED_table.descriptor[i].EOWN = 0;
 
// Assign a data buffer to each descriptor
eth_data->TX_ED_table.descriptor[i].BUFFER_ADDR = VA_TO_PA((uint32_t)eth_data->TX_ED_buffer[i]);
}
for (i = 0; i < ETH_RX_DESCRIPTOR_COUNT; i++) {
// Set the NPV values for each descriptor (linear list)
eth_data->RX_ED_table.descriptor[i].NPV = 0;
 
// Set the EOWN values for each descriptor
eth_data->RX_ED_table.descriptor[i].EOWN = 1;
 
// Assign a data buffer to each descriptor
eth_data->RX_ED_table.descriptor[i].BUFFER_ADDR = VA_TO_PA((uint32_t)eth_data->RX_ED_buffer[i]);
}
 
// On the last descriptor, save the address to the beginning of the list
eth_data->TX_ED_table.descriptor[ETH_TX_DESCRIPTOR_COUNT-1].NPV = 1;
eth_data->RX_ED_table.descriptor[ETH_RX_DESCRIPTOR_COUNT-1].NPV = 1;
 
// Set the last RX descriptor EOWN to software, thus using list configuration
// eth_data->TX_ED_table.descriptor[ETH_TX_DESCRIPTOR_COUNT-1].EOWN = 0;
// eth_data->RX_ED_table.descriptor[ETH_RX_DESCRIPTOR_COUNT-1].EOWN = 0;
 
// Loop the end of the descriptor table to the beginning (ring configuration)
eth_data->TX_ED_table.next_ED = VA_TO_PA((uint32_t)eth_data->TX_ED_table.descriptor);
eth_data->RX_ED_table.next_ED = VA_TO_PA((uint32_t)eth_data->RX_ED_table.descriptor);
 
// Save the head of the table to the corresponding ETH register
ETHTXST = VA_TO_PA((uint32_t)eth_data->TX_ED_table.descriptor);
ETHRXST = VA_TO_PA((uint32_t)eth_data->RX_ED_table.descriptor);
 
// Ethernet Initialization Sequence: see section 35.4.10 in the PIC32 Family Reference Manual
// Part 1. Ethernet Controller Initialization
IEC1bits.ETHIE = 0; // Disable ethernet interrupts
ETHCON1bits.ON = 0; // Disable the ethernet module
ETHCON1bits.TXRTS = 0; // Stop transmit logic
ETHCON1bits.RXEN = 0; // Stop receive logic
ETHCON1bits.AUTOFC = 0;
ETHCON1bits.MANFC = 0;
while (ETHSTATbits.ETHBUSY);
IFS1bits.ETHIF = 0; // Clear interrupt flags
ETHIENCLR = 0xFFFF; // Clear the ETHIEN register (interrupt enable)
 
// Part 2. MAC Init
EMAC1CFG1bits.SOFTRESET = 1; // Put the MACMII in reset
EMAC1CFG1bits.SOFTRESET = 0;
// Default I/O configuration, RMII operating mode
EMAC1SUPPbits.RESETRMII = 1; // Reset the MAC RMII module
EMAC1MCFGbits.RESETMGMT = 1; // Reset the MII management module
EMAC1MCFGbits.RESETMGMT = 0;
EMAC1MCFGbits.CLKSEL = 0x8; // Set the MIIM PHY clock to SYSCLK/40
while(EMAC1MINDbits.MIIMBUSY);
 
// Part 3. PHY Init
// Contrary to the ref manual, the ETH module needs to be enabled for the MIIM to work
 
ETHCON1bits.ON = 1; // Enable the ethernet module
uint16_t value;
// Reset the PHY chip
ETH_PHY_Write(PHY_ADDRESS, 0x0, 0x8000);
do {
value = ETH_PHY_Read(PHY_ADDRESS, 0x0);
} while (value & 0x8000 != 0);
 
// Delay to wait for the link to be established
// Something needs to be done about this. 5s is WAY too long to wait
Delay_MS(5000);
// Wait for auto-negotiation to finish
do {
value = ETH_PHY_Read(PHY_ADDRESS, 0x1F); // Acquire link status
} while (value & 0x1000 == 0);
 
ETHCON1bits.ON = 0; // Disable the ethernet module before changing other settings
// Part 4. MAC Configuration
EMAC1CFG1bits.RXENABLE = 1; // Enable the MAC receiving of frames
EMAC1CFG1bits.TXPAUSE = 1; // Enable PAUSE flow control frames
EMAC1CFG1bits.RXPAUSE = 1; // Enable processing of PAUSE control frames
EMAC1CFG2bits.AUTOPAD = 0; // No auto-detection for VLAN padding
EMAC1CFG2bits.VLANPAD = 0; // MAC does not perform padding of short frames
EMAC1CFG2bits.PADENABLE = 1; // Pad all short frames
EMAC1CFG2bits.CRCENABLE = 1; // Append a CRC to every frame
EMAC1CFG2bits.HUGEFRM = 1; // Allow frames of any length
EMAC1CFG2bits.LENGTHCK = 0; // Check the frame lengths to the length/type field
if ((value & 0x14) || (value & 0x18)) {
EMAC1CFG2bits.FULLDPLX = 1; // Operate in full-duplex mode
EMAC1IPGT = 0x15; // Back-to-back interpacket gap @ 0.96us/9.6us
// LED1_LAT = 1;
} else {
EMAC1CFG2bits.FULLDPLX = 0; // Operate in half-duplex mode
EMAC1IPGT = 0x12; // Back-to-back interpacket gap @ 0.96us/9.6us
// LED2_LAT = 1;
}
if ((value & 0x08) || (value & 0x18)) {
EMAC1SUPPbits.SPEEDRMII = 1; // 100Mbps mode
// LED3_LAT = 1;
} else {
EMAC1SUPPbits.SPEEDRMII = 0; // 10Mbps mode
// LED4_LAT = 1;
}
EMAC1IPGRbits.NB2BIPKTGP1 = 0xC; // Set some other delay gap values
EMAC1IPGRbits.NB2BIPKTGP2 = 0x12;
EMAC1CLRTbits.CWINDOW = 0x37; // Set collision window to count of frame bytes
EMAC1CLRTbits.RETX = 0xF; // Set number of retransmission attempts
EMAC1MAXF = 0x7F4; // Set the maximum frame length to 2046 bits
// Default MAC address is 00-04-A3-1A-4C-FC
// Set MAC address to 00-18-3E-00-D7-EB
EMAC1SA0 = 0xEBD7;
EMAC1SA1 = 0x003E;
EMAC1SA2 = 0x1800;
 
// Part 5. Ethernet Controller Initialization cont.
// Flow control is off by default!
ETHRXFCbits.HTEN = 0; // Disable hash table filtering
ETHRXFCbits.MPEN = 0; // Disable magic packet filtering
ETHRXFCbits.PMMODE = 0; // Disable pattern matching
ETHRXFCbits.CRCERREN = 0; // Disable CRC error collection filtering
ETHRXFCbits.CRCOKEN = 0; // Disable CRC filtering
ETHRXFCbits.RUNTERREN = 0; // Disable runt error collection filtering
ETHRXFCbits.RUNTEN = 0; // Disable runt filtering
ETHRXFCbits.UCEN = 1; // Enable unicast filtering
ETHRXFCbits.NOTMEEN = 0; // Disable acceptance of packets to other destinations
ETHRXFCbits.MCEN = 0; // Disable multicast filtering
ETHRXFCbits.BCEN = 0; // Disable broadcast filtering
 
ETHCON2bits.RXBUF_SZ = 0x7F; // Set RX data buffer size to 2032 bytes
 
ETHIENbits.TXBUSEIE = 1; // Enable interrupt on transmit BVCI bus error
ETHIENbits.RXBUSEIE = 1; // Enable interrupt on receive BVCI bus error
ETHIENbits.RXDONEIE = 1; // Enable interrupt on packet received
// ETHIENbits.PKTPENDIE = 1; // Enable interrupt on packet pending
// ETHIENbits.RXACTIE = 1;
ETHIENbits.TXDONEIE = 1; // Enable interrupt on packet sent
ETHIENbits.TXABORTIE = 1; // Enable interrupt on packet send aborted
 
IPC12bits.ETHIP = 1; // Set interrupt priority to 2
IPC12bits.ETHIS = 1; // Set intererupt sub-priority to 2
IEC1bits.ETHIE = 1; // Enable ethernet interrupts
 
EMAC1SUPPbits.RESETRMII = 0; // Bring the RMII module out of reset
ETHCON1bits.RXEN = 1; // Start receive logic
ETHCON1bits.ON = 1; // Enable the ethernet module
 
INTEnableInterrupts();
}
 
/* Reads from the specified register on the PHY chip */
uint16_t ETH_PHY_Read(uint8_t address, uint8_t reg) {
EMAC1MADR = reg | (address << 8);
EMAC1MCMDbits.READ = 1;
Nop();Nop();Nop();
while (EMAC1MINDbits.MIIMBUSY);
EMAC1MCMDbits.READ = 0;
return EMAC1MRDD;
}
 
/* Write to the specified register on the PHY chip */
void ETH_PHY_Write(uint8_t address, uint8_t reg, uint16_t value) {
EMAC1MADR = reg | (address << 8);
EMAC1MWTD = value;
Nop();Nop();Nop();
while (EMAC1MINDbits.MIIMBUSY);
}
 
/* Queries the number of pending packets */
uint8_t ETH_Recv_Queue(void) {
return ETHSTATbits.BUFCNT;
}
 
/* Function to read a single packet (<2014 bytes) */
uint8_t ETH_Read_Packet(uint8_t *buffer, uint16_t *length) {
uint16_t i, j;
uint16_t size;
uint8_t descriptor_index = eth_data->RX_descriptor_index;
 
// Look for the first descriptor where EOWN is cleared and SOP/EOP is set
for (i = 0; i < ETH_RX_DESCRIPTOR_COUNT; i++) {
if ((eth_data->RX_ED_table.descriptor[descriptor_index].EOWN == 0) &&
(eth_data->RX_ED_table.descriptor[descriptor_index].SOP == 1) &&
(eth_data->RX_ED_table.descriptor[descriptor_index].EOP == 1)) {
 
// Read the packet data values into the buffer
size = eth_data->RX_ED_table.descriptor[descriptor_index].BYTE_COUNT - 18;
for (j = 0; j < size; j++) {
buffer[j] = eth_data->RX_ED_buffer[descriptor_index][j+14];
}
*length = size;
 
// Reset the descriptors
eth_data->RX_ED_table.descriptor[descriptor_index].SOP = 0;
eth_data->RX_ED_table.descriptor[descriptor_index].EOP = 0;
eth_data->RX_ED_table.descriptor[descriptor_index].EOWN = 1;
 
eth_data->RX_descriptor_index = (descriptor_index == ETH_RX_DESCRIPTOR_COUNT - 1) ? 0 : descriptor_index + 1;
 
ETHCON1bits.BUFCDEC = 1;
return 0;
 
} else {
descriptor_index = (descriptor_index == ETH_RX_DESCRIPTOR_COUNT - 1) ? 0 : descriptor_index + 1;
}
}
 
return 1;
}
 
/* Function to send a single packet (<2018 bytes) */
uint8_t ETH_Write_Packet(ETH_MAC_ADDRESS dest, ETH_MAC_ADDRESS src, uint16_t length, uint8_t *buffer) {
uint16_t i;
uint16_t write_index = 0;
uint16_t read_index = 0;
uint16_t descriptor_index = eth_data->TX_descriptor_index;
 
// Do a quick sanity check to ensure that we have enough memory to send the message
if (length > ETH_TX_ED_BUFFER_SIZE - 14)
return 1;
 
// Fill the descriptor
eth_data->TX_ED_table.descriptor[descriptor_index].TSV.registers[0] = 0;
eth_data->TX_ED_table.descriptor[descriptor_index].TSV.registers[1] = 0;
eth_data->TX_ED_table.descriptor[descriptor_index].EOWN = 1;
eth_data->TX_ED_table.descriptor[descriptor_index].SOP = 1;
eth_data->TX_ED_table.descriptor[descriptor_index].EOP = 1;
 
for (i = 0; i < 6; i++) {
eth_data->TX_ED_buffer[descriptor_index][write_index] = dest.bytes[i];
write_index++;
}
for (i = 0; i < 6; i++) {
eth_data->TX_ED_buffer[descriptor_index][write_index] = src.bytes[i];
write_index++;
}
eth_data->TX_ED_buffer[descriptor_index][write_index] = length >> 8;
eth_data->TX_ED_buffer[descriptor_index][write_index+1] = length;
write_index += 2;
 
 
eth_data->TX_ED_table.descriptor[descriptor_index].BYTE_COUNT = length + 14;
 
for (i = 0; i < length; i++) {
eth_data->TX_ED_buffer[descriptor_index][write_index] = buffer[read_index];
write_index++;
read_index++;
}
 
// Wait for any previous transmits to finish before sending
while (ETHSTATbits.TXBUSY);
ETHCON1bits.TXRTS = 1;
while (ETHSTATbits.TXBUSY);
 
eth_data->TX_descriptor_index = (descriptor_index == ETH_TX_DESCRIPTOR_COUNT - 1) ? 0 : descriptor_index + 1;
return 0;
}
 
void __ISR(_ETH_VECTOR, ipl1) __ETH_Interrupt_Handler(void) {
// uint32_t value = ETHIRQ;
if (ETHIRQbits.TXBUSE) {
// TX bus error, something -should- be done
Reset_Board(BOARD_MODE_ETHERNET);
ETHIRQbits.TXBUSE = 0;
}
if (ETHIRQbits.RXBUSE) {
// RX bus error, something -should- be done
Reset_Board(BOARD_MODE_ETHERNET);
ETHIRQbits.RXBUSE = 0;
}
if (ETHIRQbits.RXDONE) {
// Call the previously saved function
if (eth_data->rx_callback != NULL)
(*eth_data->rx_callback)();
ETHIRQbits.RXDONE = 0;
}
// if (ETHIRQbits.PKTPEND) {
//
// ETHIRQbits.PKTPEND = 0;
// }
if (ETHIRQbits.TXDONE) {
// Call the previously saved function
if (eth_data->tx_callback != NULL)
(*eth_data->tx_callback)();
ETHIRQbits.TXDONE = 0;
}
if (ETHIRQbits.TXABORT) {
// TX aborted, do we care?
ETHIRQbits.TXABORT = 0;
}
if (ETHIRQbits.RXBUFNA) {
// This is a serious error!
// TODO: handle this
Reset_Board(BOARD_MODE_ETHERNET);
ETHIRQbits.RXBUFNA = 0;
}
if (ETHIRQbits.RXOVFLW) {
// This is a serious error!
// TODO: handle this
Reset_Board(BOARD_MODE_ETHERNET);
ETHIRQbits.RXOVFLW = 0;
}
 
IFS1bits.ETHIF = 0;
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/ETHERNET.h
0,0 → 1,162
#ifndef ETHERNET_H
#define ETHERNET_H
 
#define ETH_TX_DESCRIPTOR_COUNT 2
#define ETH_RX_DESCRIPTOR_COUNT 10
#define ETH_TX_ED_BUFFER_SIZE 2032
#define ETH_RX_ED_BUFFER_SIZE 2032
 
#ifdef CEREBOT_MX7CK
#define PHY_RESET_TRIS TRISAbits.TRISA6
#define PHY_RESET_LAT LATAbits.LATA6
#endif
#ifdef CEREBOT_32MX7
#define PHY_RESET_TRIS TRISEbits.TRISE9
#define PHY_RESET_LAT LATEbits.LATE9
#endif
#define ETH_MDC_TRIS TRISDbits.TRISD11
#define ETH_MDIO_TRIS TRISDbits.TRISD8
#define ETH_TXEN_TRIS TRISDbits.TRISD6
#define ETH_TXD0_TRIS TRISFbits.TRISF1
#define ETH_TXD1_TRIS TRISFbits.TRISF0
#define ETH_RXCLK_TRIS TRISGbits.TRISG9
#define ETH_RXDV_TRIS TRISGbits.TRISG8
#define ETH_RXD0_TRIS TRISBbits.TRISB12
#define ETH_RXD1_TRIS TRISBbits.TRISB13
#define ETH_RXERR_TRIS TRISBbits.TRISB11
 
#define PHY_ADDRESS 0x0
 
typedef union {
struct {
uint8_t BYTE_0;
uint8_t BYTE_1;
uint8_t BYTE_2;
uint8_t BYTE_3;
uint8_t BYTE_4;
uint8_t BYTE_5;
};
uint8_t bytes[6];
} ETH_MAC_ADDRESS;
 
typedef union {
struct {
// Bits 31:0
unsigned BYTE_COUNT : 16; // Total bytes in frame not counting collided bytes
unsigned COLLISION_COUNT : 4; // Number of collisions current packet incurred durrent transmit attempts
unsigned CRC_ERROR : 1; // Attached CRC did not match the internal generated CRC
unsigned LENGTH_CHECK_ERROR : 1; // Frame length field value in packet does not match actual data byte length and is not a Type field
unsigned LENGTH_OUT_OF_RANGE : 1; // Frame type/length field was larger than 1500 bytes
unsigned DONE : 1; // Transmit of packet was completed
unsigned MULTICASE : 1; // Destination address was a multicast address
unsigned BROADCAST : 1; // Destination address was a broadcast address
unsigned PACKET_DEFER : 1; // Packet was deferred for at least one attempt
unsigned EXCESSIVE_DEFER : 1; // Packet was defered in excess of 6071/24287 nibble(100Mbps)/bit(10Mbps) times
unsigned MAXIMUM_COLLISION : 1; // Packet aborted, number of collisions exceeded RETX
unsigned LATE_COLLISION : 1; // Collision occurred beyond the collision window (512 bit times)
unsigned GIANT : 1; // Frame byte count greater than MACMAXF
unsigned UNDERRUN : 1; // Failed to transfer complete packet to the transmit MAC module
// Bits 63:32
unsigned BYTES_TRANSMITTED : 16; // Total bytes transmitted on wire (including collisions)
unsigned CONTROL_FRAME : 1; // Frame transmitted was a control frame
unsigned PAUSE_CONTROL_FRAME : 1; // Frame transmitted was a control frame with a valid PAUSE Op code
unsigned BACKPRESSURE : 1; // Carrier-sense method backpressure was previously applied
unsigned VLAN_TAGGED : 1; // Frame length/type field contained 0x8100 (VLAN protocol identifier)
unsigned : 12;
};
uint32_t registers[2];
} ETH_TRANSMIT_STATUS_VECTOR;
 
typedef union {
struct {
// Bits 31:0
unsigned BYTE_COUNT : 16; // Length of received frame
unsigned LONG_DROP_EVENT : 1; // Packet over 50000 bit times occured or packet since last RSV was dropped
unsigned RXDV_EVENT : 1; // Last receive event seen not long enough to be a valid packet
unsigned CARRIER_EVENT : 1; // Carrier event detected, noted, and reported
unsigned CODE_VIOLATION : 1; // MII data does not represent a valid data code when MRXER asserted
unsigned CRC_ERROR : 1; // Frame CRC does not match the CRC calculated by the receiver MAC
unsigned LENGTH_CHECK_ERROR : 1; // Frame length field value doe snot match the actual data byte length
unsigned LENGTH_OUT_OF_RANGE : 1; // Frame type/length field was larger than 1500 bytes
unsigned RECEIVE_OK : 1; // Packet has a valid CRC and no symbol errors
unsigned MULTICAST : 1; // Packet had a valid multicast address
unsigned BROADCAST : 1; // Packet had a valid broadcast address
unsigned DRIBBLE_NIBBLE : 1; // An additional 1-7 bits received after packet
unsigned CONTROL_FRAME : 1; // Frame recognized as a control frame
unsigned PAUSE_CONTROL_FRAME : 1; // Frame recognized as a control frame with a valid PAUSE Op code
unsigned UNKNOWN_OP_CODE : 1; // Frame recognized as a control frame but with an unknown Op code
unsigned VLAN_TAGGED : 1; // Frame recognized as a VLAN tagged frame
unsigned : 1;
// Bits 63:32;
unsigned PKT_CHECKSUM : 16; // RX packet payload checksum of this descriptor's packet
unsigned : 8;
unsigned RUNT_PACKET : 1; // Runt packet
unsigned BROADCAST_OR_NOT_DEST : 1; // NOT unicast match AND NOT multicast match
unsigned HASH_TABLE_MATCH : 1; // Hash table match
unsigned MAGIC_PACKET_MATCH : 1; // Magic packet match
unsigned PATTERN_MATCH : 1; // Pattern match
unsigned UNICAST_MATCH : 1; // Unicast match
unsigned BROADCAST_MATCH : 1; // Broadcast match
unsigned MULTICAST_MATCH : 1; // Multicast match
};
uint32_t registers[2];
} ETH_RECEIVE_STATUS_VECTOR;
 
typedef struct {
unsigned : 7;
unsigned EOWN : 1; // Ethernet controller own bit (1 = ED owned by controller, do not modify)
unsigned NPV : 1; // Next ED pointer valid enable bit (1 = NEXT_ED field exists)
unsigned : 7;
unsigned BYTE_COUNT : 11; // Number of bytes to be transmited for this descriptor (1-2047)
unsigned : 3;
unsigned EOP : 1; // End of packet enable bit (1 = transmit end of packet delimiter)
unsigned SOP : 1; // Start of packet enable bit (1 = transmit start of packet delimiter)
uint32_t BUFFER_ADDR; // Starting point address of the data buffer
ETH_TRANSMIT_STATUS_VECTOR TSV; // Transmit status vector bits
} ETH_TX_ETHERNET_DESCRIPTOR;
 
typedef struct {
unsigned : 7;
unsigned EOWN : 1; // Ethernet controller own bit (1 = ED owned by controller, do not modify)
unsigned NPV : 1; // Next ED pointer valid enable bit (1 = NEXT_ED field exists)
unsigned : 7;
unsigned BYTE_COUNT : 11; // Number of bytes to be transmited for this descriptor (1-2047)
unsigned : 3;
unsigned EOP : 1; // End of packet enable bit (1 = transmit end of packet delimiter)
unsigned SOP : 1; // Start of packet enable bit (1 = transmit start of packet delimiter)
uint32_t BUFFER_ADDR; // Starting point address of the data buffer
ETH_RECEIVE_STATUS_VECTOR RSV; // Transmit status vector bits
} ETH_RX_ETHERNET_DESCRIPTOR;
 
typedef struct {
ETH_TX_ETHERNET_DESCRIPTOR descriptor[ETH_TX_DESCRIPTOR_COUNT];
uint32_t next_ED;
} ETH_TX_DESCRIPTOR_TABLE;
 
typedef struct {
ETH_RX_ETHERNET_DESCRIPTOR descriptor[ETH_RX_DESCRIPTOR_COUNT];
uint32_t next_ED;
} ETH_RX_DESCRIPTOR_TABLE;
 
typedef struct {
ETH_TX_DESCRIPTOR_TABLE TX_ED_table;
ETH_RX_DESCRIPTOR_TABLE RX_ED_table;
uint8_t TX_ED_buffer[ETH_TX_DESCRIPTOR_COUNT][ETH_TX_ED_BUFFER_SIZE];
uint8_t RX_ED_buffer[ETH_RX_DESCRIPTOR_COUNT][ETH_RX_ED_BUFFER_SIZE];
uint8_t TX_descriptor_index;
uint8_t RX_descriptor_index;
void (*tx_callback)(void);
void (*rx_callback)(void);
} ETH_DATA;
 
void ETH_Init(ETH_DATA *data, void(*tx_callback)(void), void(*rx_callback)(void));
 
uint16_t ETH_PHY_Read(uint8_t address, uint8_t reg);
void ETH_PHY_Write(uint8_t address, uint8_t reg, uint16_t value);
 
uint8_t ETH_Recv_Queue(void);
uint8_t ETH_Read_Packet(uint8_t *buffer, uint16_t *length);
uint8_t ETH_Write_Packet(ETH_MAC_ADDRESS dest, ETH_MAC_ADDRESS src, uint16_t length, uint8_t *buffer);
 
#endif /* ETHERNET_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/Ethernet API/cube.py
0,0 → 1,151
import socket, struct, time
 
# Set the address of the Cerebot board
dst_addr = '00183E00D7EB'.decode('hex')
# Open a socket on the eth0
sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
sock.bind(("eth0", 0x1))
# Acquire MAC address of local machine
if_name, if_proto, pkt_type, hw_type, hw_addr = sock.getsockname()
 
# Create and initialize the frame buffer
frame_buffer_size = 1536
frame_buffer = [0] * frame_buffer_size
 
def cube_init():
'''Sets the cube into ethernet mode.'''
# Generate and send the frame
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 1)
txOpcode = "01".decode('hex')
sock.send(txFrame + txOpcode)
# Wait a few seconds for the cube to reset itself
time.sleep(6)
 
def cube_reset():
'''Resets the cube into idle mode.'''
# Generate and send the frame
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 1)
txOpcode = "02".decode('hex')
sock.send(txFrame + txOpcode)
 
def cube_clear():
'''Clear the cube's internal buffer.'''
# Generate and send the frame
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 1)
txOpcode = "0A".decode('hex')
sock.send(txFrame + txOpcode)
 
def cube_brightness(value):
'''Sets the global brightness value from 0 to 255.'''
# Generate and send the frame
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 2)
txOpcode = "0B".decode('hex')
txData = format(value, '02x').decode('hex')
sock.send(txFrame + txOpcode + txData)
 
def cube_rotate(direction):
'''Rotate the entire cube (0 = clockwise, 1 = counterclockwise).'''
# Generate and send the frame
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 2)
txOpcode = "0C".decode('hex')
txData = format(direction, '02x').decode('hex')
sock.send(txFrame + txOpcode + txData)
 
def cube_rotate_shell(direction, shell):
'''Rotate a specific layer (0 = clockwise, 0 = outermost layer).'''
# Generate and send the frame
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 3)
txOpcode = "0D".decode('hex')
txData = ''.join("%02x%02x" % (direction, shell))
sock.send(txFrame + txOpcode + txData.decode('hex'))
 
# def cube_update():
# '''Update the cube with the current frame buffer.
# Note: this requires jumbo frames (1536 bytes).'''
# # Generate the header, opcode, and format the frame buffer
# txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 0x0601)
# txOpcode = "10".decode('hex')
# txData = ''.join("%02x" % (x) for x in frame_buffer)
# sock.send(txFrame + txOpcode + txData.decode('hex'))
 
def cube_update_pixel(x, y, z, r, g, b):
'''Set a specific pixel on the cube.'''
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 7)
txOpcode = "11".decode('hex')
frame = [x, y, z, r, g, b]
txData = ''.join("%02x" % (x) for x in frame)
sock.send(txFrame + txOpcode + txData.decode('hex'))
 
def cube_update():
'''Updates the cube with the current frame buffer.
The buffer is sent in three frames, one for each color channel.'''
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 514)
txOpcode = "12".decode('hex')
for c in range(3):
txColorCh = "%02x" % c
txData = ''.join( ["%02x" % (x) for x in frame_buffer[c::3]])
payload = txFrame + txOpcode + txColorCh.decode('hex') + txData.decode('hex')
sock.send(payload)
 
def cube_update_text_scrolling(string, r, g, b, update_rate):
'''Sets the scrolling text on the cube.'''
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, len(string) + 6)
txOpcode = "20".decode('hex')
txData = ''.join("%02x%02x%02x%02x%02x" % (len(string), r, g, b, update_rate))
txString = string.encode('hex')
sock.send(txFrame + txOpcode + txData.decode('hex') + txString.decode('hex'))
 
def cube_update_text_static(string, r, g, b):
'''Sets the static text on the cube.'''
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, len(string) + 5)
txOpcode = "21".decode('hex')
txData = ''.join("%02x%02x%02x%02x" % (len(string), r, g, b))
txString = string.encode('hex')
sock.send(txFrame + txOpcode + txData.decode('hex') + txString.decode('hex'))
 
def cube_update_text_insert(character, r, g, b, delay):
'''Appends a character to the beginning of the text buffer.'''
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 6)
txOpcode = "22".decode('hex')
txData = ''.join("%02x%02x%02x%02x%02x" % (r, g, b, delay, character))
sock.send(txFrame + txOpcode + txData.decode('hex'))
 
def cube_update_waterfall(c0, c1, c2, c3, c4, c5, c6, c7):
'''Fills in one row and shifts rows by one.'''
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 9)
txOpcode = "30".decode('hex')
txData = ''.join("%02x%02x%02x%02x%02x%02x%02x%02x" % (c0, c1, c2, c3, c4, c5, c6, c7))
sock.send(txFrame + txOpcode + txData.decode('hex'))
 
def cube_update_sphere(layer, r, g, b):
'''Sets the sphere layer to the specified color.'''
txFrame = struct.pack("!6s6sH", dst_addr, hw_addr, 5)
txOpcode = "31".decode('hex')
txData = ''.join("%02x%02x%02x%02x" % (layer, r, g, b))
sock.send(txFrame + txOpcode + txData.decode('hex'))
 
def fb_clear():
'''Clears the frame buffer/'''
for row in range(8):
for column in range(8):
for layer in range(8):
fb_set_pixel(row, column, layer, 0x00, 0x00, 0x00)
 
def fb_set_pixel(row, column, layer, R, G, B):
'''Sets a pixel to the given color in the frame buffer/'''
frame_buffer[layer * 192 + column * 24 + row * 3 + 0] = R
frame_buffer[layer * 192 + column * 24 + row * 3 + 1] = G
frame_buffer[layer * 192 + column * 24 + row * 3 + 2] = B
 
def fb_set_layer(layer, R, G, B):
'''Sets an entire layer to the given color in the frame buffer'''
for row in range(8):
for column in range(8):
fb_set_pixel(row, column, layer, R, G, B)
def fb_set_all(R, G, B):
'''Sets all the pixels in the frame buffer to the given color'''
for row in range(8):
for column in range(8):
for layer in range(8):
fb_set_pixel(row, column, layer, R, G, B)
/PIC Stuff/Cerebot_32MX7_LED_Cube/Ethernet API/animations.py
0,0 → 1,59
from cube import *
from time import sleep
 
def solid_colors(delay):
fb_set_all(0xFF, 0x00, 0x00)
cube_update()
sleep(delay)
fb_set_all(0x00, 0xFF, 0x00)
cube_update()
sleep(delay)
fb_set_all(0x00, 0x00, 0xFF)
cube_update()
sleep(delay)
 
def row_column_sweep(delay):
# Sweep across three colors (R,G,B)
for color in range(3):
# Sweep across each row
for row in range(8):
fb_set_clear()
for column in range(8):
for layer in range(8):
if color % 3 == 0:
fb_set_pixel(row, column, layer, 0xFF, 0x00, 0x00)
elif color % 3 == 1:
fb_set_pixel(row, column, layer, 0x00, 0xFF, 0x00)
else:
fb_set_pixel(row, column, layer, 0x00, 0x00, 0xFF)
cube_update()
sleep(delay)
# Sweep across each column
for column in range(8):
fb_set_clear()
for row in range(8):
for layer in range(8):
if color % 3 == 0:
fb_set_pixel(row, column, layer, 0xFF, 0x00, 0x00)
elif color % 3 == 1:
fb_set_pixel(row, column, layer, 0x00, 0xFF, 0x00)
else:
fb_set_pixel(row, column, layer, 0x00, 0x00, 0xFF)
cube_update()
sleep(delay)
# Sweep across each layer
for layer in range(7, -1, -1):
fb_set_clear()
for layer_2 in range(8):
if color % 3 == 0:
if layer_2 == layer:
set_layer(layer_2, 0xFF, 0x00, 0x00)
elif color % 3 == 1:
if layer_2 == layer:
set_layer(layer_2, 0x00, 0xFF, 0x00)
else:
if layer_2 == layer:
set_layer(layer_2, 0x00, 0x00, 0xFF)
cube_update()
sleep(delay)
/PIC Stuff/Cerebot_32MX7_LED_Cube/Ethernet API/main.py
0,0 → 1,44
from cube import *
import animations
from time import sleep
 
if __name__ == '__main__':
# Put the cube into ethernet mode
print "Initializing cube. Wait 6 seconds...\n"
# cube_init()
# ----- Begin animations -----
 
cube_clear()
cube_update_text("CCM LAB ", 0xFF, 0xFF, 0xFF, 100)
print "Looping animations...\n"
while(1):
 
# for i in range(9):
# cube_clear()
# cube_update_sphere(i, 0xFF, 0x00, 0x00)
# sleep(0.1)
 
cube_update_waterfall(1, 2, 3, 4, 5, 6, 7, 8)
sleep(0.1)
 
# #cube_update_pixel(x, y, z, r, g, b)
# for x in range(8):
# for y in range(8):
# for z in range(8):
# cube_update_pixel(x, y, z, 255, 255, 255)
# time.sleep(0.11)
# cube_update_pixel(x, y, z, 0, 0, 0)
# time.sleep(0.1)
# #time.sleep(0.1)
# ----- End Animations -----
 
# Reset the cube into idle mode (optional)
print "Animations done. Returning board to idle mode..."
cube_reset()
/PIC Stuff/Cerebot_32MX7_LED_Cube/UART API/CubeInterface.py
0,0 → 1,257
import serial
from CubeRawCommands import *
 
# Constants
CUBE_LAYER_COUNT = 8
CUBE_ROW_COUNT = 8
CUBE_COLUMN_COUNT = 8
CUBE_ROTATIONS = 7
GCS_REG_SIZE = 36
GCS_LAYER_SIZE = GCS_REG_SIZE * CUBE_ROW_COUNT
 
# 3 bytes per LED, 1536 total for the cube
cube_buffer = bytearray(CUBE_LAYER_COUNT*GCS_LAYER_SIZE)
rotation_counter = 0
 
# Specify the serial port to connect to
serial_port = serial.Serial()
 
'''Opens the serial port for sending commands through.'''
def Cube_Init(port, baudrate):
serial_port.port = port
serial_port.baudrate = baudrate
serial_port.open()
 
'''Clears the local buffer for LED values.'''
def Cube_Clear():
for i in range(len(cube_buffer)):
cube_buffer[i] = 0
 
'''Sets a specific pixel in the local buffer.'''
def Cube_Set_Pixel(layer, row, column, R, G, B):
# Set the specified pixel to the given color
R &= 0x0FFF
G &= 0x0FFF
B &= 0x0FFF
var = row * GCS_REG_SIZE + (column // 2 * 9)
offset = (layer * GCS_LAYER_SIZE) + var
if column % 2 == 0:
cube_buffer[offset+0] = R & 0xFF
cube_buffer[offset+1] = ((G << 4) | (R >> 8)) & 0xFF
cube_buffer[offset+2] = G >> 4
cube_buffer[offset+3] = B & 0xFF
cube_buffer[offset+4] = ((cube_buffer[offset+4] & 0xF0) | (B >> 8)) & 0xFF
elif column % 2 == 1:
cube_buffer[offset+4] = ((cube_buffer[offset+4] & 0x0F) | (R << 4)) & 0xFF
cube_buffer[offset+5] = R >> 4
cube_buffer[offset+6] = G & 0xFF
cube_buffer[offset+7] = ((B << 4) | (G >> 8)) & 0xFF
cube_buffer[offset+8] = B >> 4
 
'''Retreives a specific pixel in the local buffer.'''
def Cube_Get_Pixel(layer, row, column):
# Get and return the color for the specified pixel
R = G = B = 0
var = row * GCS_REG_SIZE + (column // 2 * 9)
offset = (layer * GCS_LAYER_SIZE) + var
if column % 2 == 0:
R = cube_buffer[offset+0] | ((cube_buffer[offset+1] & 0x0F) << 8);
G = (cube_buffer[offset+1] >> 4) | (cube_buffer[offset+2] << 4);
B = cube_buffer[offset+3] | ((cube_buffer[offset+4] & 0x0F) << 8);
elif column % 2 == 1:
R = (cube_buffer[offset+4] >> 4) | (cube_buffer[offset+5] << 4);
G = cube_buffer[offset+6] | ((cube_buffer[offset+7] & 0x0F) << 8);
B = (cube_buffer[offset+7] >> 4) | (cube_buffer[offset+8] << 4);
return [R,G,B]
 
'''Moves a value from one pixel to another in the local buffer.'''
def Cube_Move_Pixel(layer_1, row_1, column_1, layer_2, row_2, column_2):
old = Cube_Get_Pixel(layer1, row_1, column_1)
Cube_Set_Pixel(layer_2, row_2, column_2, old[0], old[1], old[2])
 
'''Rotates the specified shell in the local buffer.'''
def Cube_Rotate_Shell(shell, direction):
for layer in range(CUBE_LAYER_COUNT):
if direction == 1:
if shell == 0:
# Rotate outermost layer
old = Cube_Get_Pixel(layer, 0, 0);
Cube_Move_Pixel(layer, 0, 1, layer, 0, 0);
Cube_Move_Pixel(layer, 0, 2, layer, 0, 1);
Cube_Move_Pixel(layer, 0, 3, layer, 0, 2);
Cube_Move_Pixel(layer, 0, 4, layer, 0, 3);
Cube_Move_Pixel(layer, 0, 5, layer, 0, 4);
Cube_Move_Pixel(layer, 0, 6, layer, 0, 5);
Cube_Move_Pixel(layer, 0, 7, layer, 0, 6);
Cube_Move_Pixel(layer, 1, 7, layer, 0, 7);
Cube_Move_Pixel(layer, 2, 7, layer, 1, 7);
Cube_Move_Pixel(layer, 3, 7, layer, 2, 7);
Cube_Move_Pixel(layer, 4, 7, layer, 3, 7);
Cube_Move_Pixel(layer, 5, 7, layer, 4, 7);
Cube_Move_Pixel(layer, 6, 7, layer, 5, 7);
Cube_Move_Pixel(layer, 7, 7, layer, 6, 7);
Cube_Move_Pixel(layer, 7, 6, layer, 7, 7);
Cube_Move_Pixel(layer, 7, 5, layer, 7, 6);
Cube_Move_Pixel(layer, 7, 4, layer, 7, 5);
Cube_Move_Pixel(layer, 7, 3, layer, 7, 4);
Cube_Move_Pixel(layer, 7, 2, layer, 7, 3);
Cube_Move_Pixel(layer, 7, 1, layer, 7, 2);
Cube_Move_Pixel(layer, 7, 0, layer, 7, 1);
Cube_Move_Pixel(layer, 6, 0, layer, 7, 0);
Cube_Move_Pixel(layer, 5, 0, layer, 6, 0);
Cube_Move_Pixel(layer, 4, 0, layer, 5, 0);
Cube_Move_Pixel(layer, 3, 0, layer, 4, 0);
Cube_Move_Pixel(layer, 2, 0, layer, 3, 0);
Cube_Move_Pixel(layer, 1, 0, layer, 2, 0);
Cube_Set_Pixel(layer, 1, 0, old[0], old[1], old[2]);
elif shell == 1:
# Rotate second to outermost layer
old = Cube_Get_Pixel(layer, 1, 1);
Cube_Move_Pixel(layer, 1, 2, layer, 1, 1);
Cube_Move_Pixel(layer, 1, 3, layer, 1, 2);
Cube_Move_Pixel(layer, 1, 4, layer, 1, 3);
Cube_Move_Pixel(layer, 1, 5, layer, 1, 4);
Cube_Move_Pixel(layer, 1, 6, layer, 1, 5);
Cube_Move_Pixel(layer, 2, 6, layer, 1, 6);
Cube_Move_Pixel(layer, 3, 6, layer, 2, 6);
Cube_Move_Pixel(layer, 4, 6, layer, 3, 6);
Cube_Move_Pixel(layer, 5, 6, layer, 4, 6);
Cube_Move_Pixel(layer, 6, 6, layer, 5, 6);
Cube_Move_Pixel(layer, 6, 5, layer, 6, 6);
Cube_Move_Pixel(layer, 6, 4, layer, 6, 5);
Cube_Move_Pixel(layer, 6, 3, layer, 6, 4);
Cube_Move_Pixel(layer, 6, 2, layer, 6, 3);
Cube_Move_Pixel(layer, 6, 1, layer, 6, 2);
Cube_Move_Pixel(layer, 5, 1, layer, 6, 1);
Cube_Move_Pixel(layer, 4, 1, layer, 5, 1);
Cube_Move_Pixel(layer, 3, 1, layer, 4, 1);
Cube_Move_Pixel(layer, 2, 1, layer, 3, 1);
Cube_Set_Pixel(layer, 2, 1, old[0], old[1], old[2]);
elif shell == 2:
# Rotate second to innermost layer
old = Cube_Get_Pixel(layer, 2, 2);
Cube_Move_Pixel(layer, 2, 3, layer, 2, 2);
Cube_Move_Pixel(layer, 2, 4, layer, 2, 3);
Cube_Move_Pixel(layer, 2, 5, layer, 2, 4);
Cube_Move_Pixel(layer, 3, 5, layer, 2, 5);
Cube_Move_Pixel(layer, 4, 5, layer, 3, 5);
Cube_Move_Pixel(layer, 5, 5, layer, 4, 5);
Cube_Move_Pixel(layer, 5, 4, layer, 5, 5);
Cube_Move_Pixel(layer, 5, 3, layer, 5, 4);
Cube_Move_Pixel(layer, 5, 2, layer, 5, 3);
Cube_Move_Pixel(layer, 4, 2, layer, 5, 2);
Cube_Move_Pixel(layer, 3, 2, layer, 4, 2);
Cube_Set_Pixel(layer, 3, 2, old[0], old[1], old[2]);
elif shell == 3:
# Rotate innermost layer
old = Cube_Get_Pixel(layer, 3, 3);
Cube_Move_Pixel(layer, 3, 4, layer, 3, 3);
Cube_Move_Pixel(layer, 4, 4, layer, 3, 4);
Cube_Move_Pixel(layer, 4, 3, layer, 4, 4);
Cube_Set_Pixel(layer, 4, 3, old[0], old[1], old[2]);
else:
if shell == 0:
# Rotate outermost layer
old = Cube_Get_Pixel(layer, 0, 0);
Cube_Move_Pixel(layer, 1, 0, layer, 0, 0);
Cube_Move_Pixel(layer, 2, 0, layer, 1, 0);
Cube_Move_Pixel(layer, 3, 0, layer, 2, 0);
Cube_Move_Pixel(layer, 4, 0, layer, 3, 0);
Cube_Move_Pixel(layer, 5, 0, layer, 4, 0);
Cube_Move_Pixel(layer, 6, 0, layer, 5, 0);
Cube_Move_Pixel(layer, 7, 0, layer, 6, 0);
Cube_Move_Pixel(layer, 7, 1, layer, 7, 0);
Cube_Move_Pixel(layer, 7, 2, layer, 7, 1);
Cube_Move_Pixel(layer, 7, 3, layer, 7, 2);
Cube_Move_Pixel(layer, 7, 4, layer, 7, 3);
Cube_Move_Pixel(layer, 7, 5, layer, 7, 4);
Cube_Move_Pixel(layer, 7, 6, layer, 7, 5);
Cube_Move_Pixel(layer, 7, 7, layer, 7, 6);
Cube_Move_Pixel(layer, 6, 7, layer, 7, 7);
Cube_Move_Pixel(layer, 5, 7, layer, 6, 7);
Cube_Move_Pixel(layer, 4, 7, layer, 5, 7);
Cube_Move_Pixel(layer, 3, 7, layer, 4, 7);
Cube_Move_Pixel(layer, 2, 7, layer, 3, 7);
Cube_Move_Pixel(layer, 1, 7, layer, 2, 7);
Cube_Move_Pixel(layer, 0, 7, layer, 1, 7);
Cube_Move_Pixel(layer, 0, 6, layer, 0, 7);
Cube_Move_Pixel(layer, 0, 5, layer, 0, 6);
Cube_Move_Pixel(layer, 0, 4, layer, 0, 5);
Cube_Move_Pixel(layer, 0, 3, layer, 0, 4);
Cube_Move_Pixel(layer, 0, 2, layer, 0, 3);
Cube_Move_Pixel(layer, 0, 1, layer, 0, 2);
Cube_Set_Pixel(layer, 0, 1, old[0], old[1], old[2]);
if shell == 1:
# Rotate second to outermost layer
old = Cube_Get_Pixel(layer, 1, 1);
Cube_Move_Pixel(layer, 2, 1, layer, 1, 1);
Cube_Move_Pixel(layer, 3, 1, layer, 2, 1);
Cube_Move_Pixel(layer, 4, 1, layer, 3, 1);
Cube_Move_Pixel(layer, 5, 1, layer, 4, 1);
Cube_Move_Pixel(layer, 6, 1, layer, 5, 1);
Cube_Move_Pixel(layer, 6, 2, layer, 6, 1);
Cube_Move_Pixel(layer, 6, 3, layer, 6, 2);
Cube_Move_Pixel(layer, 6, 4, layer, 6, 3);
Cube_Move_Pixel(layer, 6, 5, layer, 6, 4);
Cube_Move_Pixel(layer, 6, 6, layer, 6, 5);
Cube_Move_Pixel(layer, 5, 6, layer, 6, 6);
Cube_Move_Pixel(layer, 4, 6, layer, 5, 6);
Cube_Move_Pixel(layer, 3, 6, layer, 4, 6);
Cube_Move_Pixel(layer, 2, 6, layer, 3, 6);
Cube_Move_Pixel(layer, 1, 6, layer, 2, 6);
Cube_Move_Pixel(layer, 1, 5, layer, 1, 6);
Cube_Move_Pixel(layer, 1, 4, layer, 1, 5);
Cube_Move_Pixel(layer, 1, 3, layer, 1, 4);
Cube_Move_Pixel(layer, 1, 2, layer, 1, 3);
Cube_Set_Pixel(layer, 1, 2, old[0], old[1], old[2]);
if shell == 2:
# Rotate second to innermost layer
old = Cube_Get_Pixel(layer, 2, 2);
Cube_Move_Pixel(layer, 3, 2, layer, 2, 2);
Cube_Move_Pixel(layer, 4, 2, layer, 3, 2);
Cube_Move_Pixel(layer, 5, 2, layer, 4, 2);
Cube_Move_Pixel(layer, 5, 3, layer, 5, 2);
Cube_Move_Pixel(layer, 5, 4, layer, 5, 3);
Cube_Move_Pixel(layer, 5, 5, layer, 5, 4);
Cube_Move_Pixel(layer, 4, 5, layer, 5, 5);
Cube_Move_Pixel(layer, 3, 5, layer, 4, 5);
Cube_Move_Pixel(layer, 2, 5, layer, 3, 5);
Cube_Move_Pixel(layer, 2, 4, layer, 2, 5);
Cube_Move_Pixel(layer, 2, 3, layer, 2, 4);
Cube_Set_Pixel(layer, 2, 3, old[0], old[1], old[2]);
if shell == 3:
# Rotate innermost layer
old = Cube_Get_Pixel(layer, 3, 3);
Cube_Move_Pixel(layer, 4, 3, layer, 3, 3);
Cube_Move_Pixel(layer, 4, 4, layer, 4, 3);
Cube_Move_Pixel(layer, 3, 4, layer, 4, 4);
Cube_Set_Pixel(layer, 3, 4, old[0], old[1], old[2]);
 
'''Rotates the entire cube in the local buffer.'''
def Cube_Rotate(direction):
# Rotate outermost layer
Cube_Rotate_Shell(0, direction);
# Rotate second to outermost layer
if ((rotation_counter != 1) and (rotation_counter != 5)):
Cube_Rotate_Shell(1, direction);
# Rotate second to innermost layer
if ((rotation_counter != 0) and (rotation_counter != 2) and (rotation_counter != 4) and (rotation_counter != 6)):
Cube_Rotate_Shell(2, direction);
# Rotate innermost layer
if ((rotation_counter == 3) or (rotation_counter == 7)):
Cube_Rotate_Shell(3, direction);
 
if (direction == 0):
if rotation_counter == CUBE_ROTATIONS - 1:
rotation_counter = 0
else:
rotation_counter = rotation_counter + 1
else:
if rotation_counter == 0:
rotation_counter = CUBE_ROTATIONS - 1
else:
rotation_counter = rotation_counter - 1
 
'''Write the local buffer to the cube.'''
def Cube_Update():
serial_port.write(CMD_Set_All(cube_buffer))
/PIC Stuff/Cerebot_32MX7_LED_Cube/UART API/CubeMain.py
0,0 → 1,62
import serial,time
from CubeRawCommands import *
from CubeInterface import *
 
def Animation_Row_Column_Sweep(iterations, delay):
for z in range(iterations):
for i in range(3):
for j in range(CUBE_ROW_COUNT):
Cube_Clear();
for k in range(CUBE_COLUMN_COUNT):
if (i % 3 == 0):
for a in range(CUBE_LAYER_COUNT):
Cube_Set_Pixel(a,j,k,0xFF,0x00,0x00)
elif (i % 3 == 1):
for a in range(CUBE_LAYER_COUNT):
Cube_Set_Pixel(a,j,k,0x00,0xFF,0x00)
else:
for a in range(CUBE_LAYER_COUNT):
Cube_Set_Pixel(a,j,k,0x00,0x00,0xFF)
Cube_Update()
time.sleep(delay)
for j in range(CUBE_ROW_COUNT):
Cube_Clear();
for k in range(CUBE_COLUMN_COUNT):
if (i % 3 == 0):
for a in range(CUBE_LAYER_COUNT):
Cube_Set_Pixel(a,k,j,0xFF,0x00,0x00)
elif (i % 3 == 1):
for a in range(CUBE_LAYER_COUNT):
Cube_Set_Pixel(a,k,j,0x00,0xFF,0x00)
else:
for a in range(CUBE_LAYER_COUNT):
Cube_Set_Pixel(a,k,j,0x00,0x00,0xFF)
Cube_Update()
time.sleep(delay)
for j in range(CUBE_LAYER_COUNT-1, -1, -1):
Cube_Clear();
if (i % 3 == 0):
for k in range(CUBE_LAYER_COUNT):
if (k == j):
for x in range(CUBE_ROW_COUNT):
for y in range(CUBE_COLUMN_COUNT):
Cube_Set_Pixel(k,x,y,0xFF,0x00,0x00)
elif (i % 3 == 1):
for k in range(CUBE_LAYER_COUNT):
if (k == j):
for x in range(CUBE_ROW_COUNT):
for y in range(CUBE_COLUMN_COUNT):
Cube_Set_Pixel(k,x,y,0x00,0xFF,0x00)
else:
for k in range(CUBE_LAYER_COUNT):
if (k == j):
for x in range(CUBE_ROW_COUNT):
for y in range(CUBE_COLUMN_COUNT):
Cube_Set_Pixel(k,x,y,0x00,0x00,0xFF)
Cube_Update()
time.sleep(delay)
 
if __name__ == '__main__':
Cube_Init('COM11', 256000)
 
Animation_Row_Column_Sweep(3,0)
/PIC Stuff/Cerebot_32MX7_LED_Cube/UART API/CubeRawCommands.py
0,0 → 1,43
'''Generates the byte array for setting the global brightness.'''
def CMD_Set_BC(brightness):
barray = bytearray.fromhex('7E 00 02 0A')
barray.extend([brightness])
barray.extend([Calculate_Checksum(barray)])
return barray
 
'''Generates the byte array for clearing all pixels.'''
def CMD_Clear():
return bytearray.fromhex('7E 00 01 0B F4')
 
'''Generates the command for setting a specific pixel.'''
def CMD_Set_Pixel(layer, row, column, r, g, b):
barray = bytearray.fromhex('7E 00 07 10')
barray.extend([layer,row,column,r,g,b,])
barray.extend([Calculate_Checksum(barray)])
return barray
 
'''Generates the command for setting the entire cube.'''
def CMD_Set_All(leds):
barray = bytearray.fromhex('7E 09 01 11')
barray.extend(leds)
barray.extend([Calculate_Checksum(barray)])
return barray
 
'''Generates the command for setting the rotating overlay text.'''
def CMD_Start_Text(r, g, b, string):
length = len(string) + 4
barray = bytearray.fromhex('7E 00')
barray.extend([length, 0x20, r, g, b])
barray.extend(string.encode())
barray.extend([Calculate_Checksum(barray)])
return barray
 
'''Generates the command for stopping the rotating overlay text.'''
def CMD_Stop_Text():
return bytes.fromhex('7E 00 01 21 DE')
 
def Calculate_Checksum(barray):
s = 0
for entry in range(3,len(barray)):
s += barray[entry]
return 255 - (s & 0xFF)
/PIC Stuff/Cerebot_32MX7_LED_Cube/TIMER4.c
0,0 → 1,60
#include "defines.h"
#include "TIMER4.h"
 
static TIMER4_DATA *timer_data_ptr;
 
void TIMER4_Init(TIMER4_DATA *data, void (*callback_ms)(void),
void (*callback_div)(void), uint32_t time_ms) {
if (data != NULL) // if ptr is null, use existing data
timer_data_ptr = data;
 
// The first callback function will be executed every ms
timer_data_ptr->callback_function_1 = callback_ms;
// The second callback function will be executed at the multiplier specified
timer_data_ptr->callback_function_2 = callback_div;
timer_data_ptr->divider = time_ms;
timer_data_ptr->count = 0;
 
INTDisableInterrupts();
 
T4CON = 0x0;
 
// Set timer to trigger every millisecond
uint16_t time = 5000;
T4CONSET = 0x0040; // Prescaler at 1:16
 
Nop();
TMR4 = 0x0; // Clear timer register
PR4 = time; // Load period register
IPC4SET = 0x00000005; // Set priority level = 1, sub-priority level = 1
IFS0CLR = 0x00010000; // Clear timer interrupt flag
IEC0SET = 0x00010000; // Enable timer interrupt
 
INTEnableInterrupts();
}
 
void TIMER4_Start(void) {
T4CONSET = 0x8000; // Start timer
}
 
void TIMER4_Stop(void) {
T4CONCLR = 0x8000; // Stop timer
}
 
void __ISR(_TIMER_4_VECTOR, ipl4) __TIMER_4_Interrupt_Handler(void) {
// Call the saved callback function
if (timer_data_ptr->callback_function_1 != NULL)
(*timer_data_ptr->callback_function_1)();
 
if (timer_data_ptr->divider != 0 && timer_data_ptr->callback_function_2 != NULL) {
if (timer_data_ptr->count == timer_data_ptr->divider) {
(*timer_data_ptr->callback_function_2)();
timer_data_ptr->count = 0;
} else {
timer_data_ptr->count++;
}
}
 
IFS0CLR = 0x00010000; // Clear the timer interrupt flag
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/TRON.c
0,0 → 1,165
#include "defines.h"
#include "CONTROLLERS.h"
#include "TRON.h"
 
static TRON_DATA *data_p;
 
void Tron_Init(TRON_DATA *data) {
data_p = data;
 
// Set starting point
data_p->p1_body[0] = (TRON_POINT){0,0,7};
data_p->p2_body[0] = (TRON_POINT){7,7,7};
 
data_p->length = 1;
data_p->delay = 800;
 
Cube_Clear();
Cube_Overlay_Clear();
 
// Draw player 1 light trail
uint32_t index;
for (index = 0; index < data_p->length - 1; index++) {
Cube_Set_Pixel(data_p->p1_body[index].z, data_p->p1_body[index].x, data_p->p1_body[index].y, TRON_PLAYER_1_COLOR);
}
Cube_Set_Pixel(data_p->p1_body[data_p->length-1].z, data_p->p1_body[data_p->length-1].x, data_p->p1_body[data_p->length-1].y, TRON_PLAYER_1_HEAD);
 
// Draw player 2 light trail
for (index = 0; index < data_p->length - 1; index++) {
Cube_Set_Pixel(data_p->p2_body[index].z, data_p->p2_body[index].x, data_p->p2_body[index].y, TRON_PLAYER_2_COLOR);
}
Cube_Set_Pixel(data_p->p2_body[data_p->length-1].z, data_p->p2_body[data_p->length-1].x, data_p->p2_body[data_p->length-1].y, TRON_PLAYER_2_HEAD);
}
 
void Tron_Main(void) {
// Main function, loops and delays while updating the frame every x milliseconds
Tron_Update_Direction(0x04,0x04);
Controller_Set_Leds(0x01,0x01);
Delay_MS(2000);
while (1) {
Tron_Update_Frame();
Delay_MS(data_p->delay);
}
}
 
void Tron_Update_Direction(uint8_t p1, uint8_t p2) {
// Determine the next direction for the trails based off the last button press
if (p1) {
TRON_P1_DIRECTION p1_dir;
p1_dir.value = p1;
data_p->p1_last_direction = p1_dir.value;
TRON_POINT p1_point = data_p->p1_body[data_p->length - 1];
if (p1_dir.up) {
p1_point.z = (p1_point.z == CUBE_LAYER_COUNT - 1) ? 0 : p1_point.z + 1;
} else if (p1_dir.down) {
p1_point.z = (p1_point.z == 0) ? CUBE_LAYER_COUNT - 1 : p1_point.z - 1;
} else if (p1_dir.forward) {
p1_point.x = (p1_point.x == CUBE_ROW_COUNT - 1) ? 0 : p1_point.x + 1;
} else if (p1_dir.right) {
p1_point.y = (p1_point.y == CUBE_COLUMN_COUNT - 1) ? 0 : p1_point.y + 1;
} else if (p1_dir.backward) {
p1_point.x = (p1_point.x == 0) ? CUBE_ROW_COUNT - 1 : p1_point.x - 1;
} else if (p1_dir.left) {
p1_point.y = (p1_point.y== 0) ? CUBE_COLUMN_COUNT - 1 : p1_point.y - 1;
}
data_p->p1_direction = p1_point;
}
if (p2) {
TRON_P2_DIRECTION p2_dir;
p2_dir.value = p2;
data_p->p2_last_direction = p2_dir.value;
TRON_POINT p2_point = data_p->p2_body[data_p->length - 1];
if (p2_dir.up) {
p2_point.z = (p2_point.z == CUBE_LAYER_COUNT - 1) ? 0 : p2_point.z + 1;
} else if (p2_dir.down) {
p2_point.z = (p2_point.z == 0) ? CUBE_LAYER_COUNT - 1 : p2_point.z - 1;
} else if (p2_dir.forward) {
p2_point.x = (p2_point.x == CUBE_ROW_COUNT - 1) ? 0 : p2_point.x + 1;
} else if (p2_dir.right) {
p2_point.y = (p2_point.y == CUBE_COLUMN_COUNT - 1) ? 0 : p2_point.y + 1;
} else if (p2_dir.backward) {
p2_point.x = (p2_point.x == 0) ? CUBE_ROW_COUNT - 1 : p2_point.x - 1;
} else if (p2_dir.left) {
p2_point.y = (p2_point.y== 0) ? CUBE_COLUMN_COUNT - 1 : p2_point.y - 1;
}
data_p->p2_direction = p2_point;
}
}
 
void Tron_Update_Frame(void) {
// Check if there is a head-on collision
if (data_p->p1_direction.x == data_p->p2_direction.x &&
data_p->p1_direction.y == data_p->p2_direction.y &&
data_p->p1_direction.z == data_p->p2_direction.z) {
Cube_Set_Pixel(data_p->p1_direction.z, data_p->p1_direction.x, data_p->p1_direction.y, TRON_COLLISION);
Delay_MS(3000);
Animation_Cube_In_Out(200, TRON_COLLISION);
Reset_Board(BOARD_MODE_IDLE);
}
 
// Check if the location that we are moving to is overlapping either trails
uint32_t index, p1_collision = 0, p2_collision = 0;
for (index = 0; index < data_p->length; index++) {
if (data_p->p1_direction.x == data_p->p1_body[index].x &&
data_p->p1_direction.y == data_p->p1_body[index].y &&
data_p->p1_direction.z == data_p->p1_body[index].z) {
p1_collision = 1;
}
if (data_p->p1_direction.x == data_p->p2_body[index].x &&
data_p->p1_direction.y == data_p->p2_body[index].y &&
data_p->p1_direction.z == data_p->p2_body[index].z) {
p1_collision = 1;
}
if (data_p->p2_direction.x == data_p->p2_body[index].x &&
data_p->p2_direction.y == data_p->p2_body[index].y &&
data_p->p2_direction.z == data_p->p2_body[index].z) {
p2_collision = 1;
}
if (data_p->p2_direction.x == data_p->p1_body[index].x &&
data_p->p2_direction.y == data_p->p1_body[index].y &&
data_p->p2_direction.z == data_p->p1_body[index].z) {
p2_collision = 1;
}
}
 
// Save the new head location of each trail
data_p->length++;
data_p->p1_body[data_p->length - 1] = data_p->p1_direction;
data_p->p2_body[data_p->length - 1] = data_p->p2_direction;
 
Cube_Clear();
// Draw player 1 light trail
for (index = 0; index < data_p->length - 1; index++) {
Cube_Set_Pixel(data_p->p1_body[index].z, data_p->p1_body[index].x, data_p->p1_body[index].y, TRON_PLAYER_1_COLOR);
}
Cube_Set_Pixel(data_p->p1_body[data_p->length-1].z, data_p->p1_body[data_p->length-1].x, data_p->p1_body[data_p->length-1].y, TRON_PLAYER_1_HEAD);
 
// Draw player 2 light trail
for (index = 0; index < data_p->length - 1; index++) {
Cube_Set_Pixel(data_p->p2_body[index].z, data_p->p2_body[index].x, data_p->p2_body[index].y, TRON_PLAYER_2_COLOR);
}
Cube_Set_Pixel(data_p->p2_body[data_p->length-1].z, data_p->p2_body[data_p->length-1].x, data_p->p2_body[data_p->length-1].y, TRON_PLAYER_2_HEAD);
 
// Indicate the point of collision and reset to idle mode
if (p1_collision || p2_collision) {
uint32_t ind = data_p->length - 1;
if (p1_collision)
Cube_Set_Pixel(data_p->p1_body[ind].z, data_p->p1_body[ind].x, data_p->p1_body[ind].y, TRON_COLLISION);
if (p2_collision)
Cube_Set_Pixel(data_p->p2_body[ind].z, data_p->p2_body[ind].x, data_p->p2_body[ind].y, TRON_COLLISION);
Delay_MS(3000);
if (p1_collision && p2_collision)
Animation_Cube_In_Out(200, TRON_COLLISION);
else if (p1_collision)
Animation_Cube_In_Out(200, TRON_PLAYER_2_HEAD);
else if (p2_collision)
Animation_Cube_In_Out(200, TRON_PLAYER_1_HEAD);
Reset_Board(BOARD_MODE_IDLE);
}
 
// Determine the next direction to take
Tron_Update_Direction(data_p->p1_last_direction, data_p->p2_last_direction);
 
// Decrease the delay between frame updates by 5ms
data_p->delay -= 5;
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/SNAKE.c
0,0 → 1,186
#include "defines.h"
#include "CONTROLLERS.h"
#include "SNAKE.h"
 
static SNAKE_DATA *data_p;
static uint32_t rand_value __attribute__((persistent));
 
void Snake_Init(SNAKE_DATA *data) {
data_p = data;
 
// Set starting point
data_p->body[0] = (SNAKE_POINT){0,0,7};
 
data_p->pos_head = 0;
data_p->pos_tail = 0;
data_p->length = 1;
data_p->level = 1;
data_p->delay = 800;
 
srand(rand_value);
 
// Generate a starting location for the candy
data_p->candy_loc = Snake_Generate_Candy();
 
// Draw the snake (head)
Cube_Clear();
uint32_t index = data_p->pos_head;
Cube_Set_Pixel(data_p->body[index].z, data_p->body[index].x, data_p->body[index].y, SNAKE_HEAD_COLOR);
while (index != data_p->pos_tail) {
if (data_p->length > 1) {
index = (index == 0) ? CUBE_PIXELS - 1 : index - 1;
Cube_Set_Pixel(data_p->body[index].z, data_p->body[index].x, data_p->body[index].y, SNAKE_BODY_COLOR);
}
}
}
 
void Snake_Main(void) {
// Main function, loops and delays while updating the frame every x milliseconds
Delay_MS(2000);
while (1) {
// Regenerate the seed upon each update so that the candy starts somewhere new every time
rand_value = rand();
Snake_Update_Frame();
Delay_MS(data_p->delay);
}
}
 
void Snake_Update_Direction(uint8_t p1, uint8_t p2) {
// Determine the next direction for the snake based off the last button press
SNAKE_DIRECTION dir;
dir.value = p1 | p2;
data_p->last_direction = dir.value;
 
SNAKE_POINT point = data_p->body[data_p->pos_head];
if (dir.up) {
point.z = (point.z == CUBE_LAYER_COUNT - 1) ? 0 : point.z + 1;
} else if (dir.down) {
point.z = (point.z == 0) ? CUBE_LAYER_COUNT - 1 : point.z - 1;
} else if (dir.forward) {
point.x = (point.x == CUBE_ROW_COUNT - 1) ? 0 : point.x + 1;
} else if (dir.right) {
point.y = (point.y == CUBE_COLUMN_COUNT - 1) ? 0 : point.y + 1;
} else if (dir.backward) {
point.x = (point.x == 0) ? CUBE_ROW_COUNT - 1 : point.x - 1;
} else if (dir.left) {
point.y = (point.y== 0) ? CUBE_COLUMN_COUNT - 1 : point.y - 1;
}
 
data_p->direction = point;
 
// Update the overlay with the candy location
Cube_Overlay_Clear();
Cube_Overlay_Set_Pixel(data_p->candy_loc.z, data_p->candy_loc.x, data_p->candy_loc.y, SNAKE_CANDY_COLOR);
}
 
void Snake_Update_Frame(void) {
uint8_t om_nom_nom = 0;
 
// Check if we are moving onto a candy, if so extend body
if (data_p->direction.x == data_p->candy_loc.x &&
data_p->direction.y == data_p->candy_loc.y &&
data_p->direction.z == data_p->candy_loc.z) {
data_p->pos_head = (data_p->pos_head == CUBE_PIXELS - 1) ? 0 : data_p->pos_head + 1;
data_p->body[data_p->pos_head] = data_p->direction;
data_p->length++;
data_p->candy_loc = Snake_Generate_Candy();
om_nom_nom = 1;
}
 
// Check if the location that we are moving to is overlapping the body
uint32_t pos = data_p->pos_tail;
while (pos != data_p->pos_head) {
if (data_p->direction.x == data_p->body[pos].x &&
data_p->direction.y == data_p->body[pos].y &&
data_p->direction.z == data_p->body[pos].z) {
// Indicate the overlapping pixel, delay, then return to idle state
Cube_Set_Pixel(data_p->direction.z, data_p->direction.x, data_p->direction.y, SNAKE_COLLISION_COLOR);
Delay_MS(3000);
Cube_Overlay_Clear();
Animation_Cube_In_Out(200, ORANGE);
Reset_Board(BOARD_MODE_IDLE);
}
pos = (pos == CUBE_PIXELS - 1) ? 0 : pos + 1;
}
 
// If we didnt eat a candy, increment the frame to move the body along
if (!om_nom_nom) {
data_p->pos_head = (data_p->pos_head == CUBE_PIXELS - 1) ? 0 : data_p->pos_head + 1;
data_p->pos_tail = (data_p->pos_tail == CUBE_PIXELS - 1) ? 0 : data_p->pos_tail + 1;
data_p->body[data_p->pos_head] = data_p->direction;
}
 
// Draw updated snake location
Cube_Clear();
uint32_t index = data_p->pos_head;
Cube_Set_Pixel(data_p->body[index].z, data_p->body[index].x, data_p->body[index].y, SNAKE_HEAD_COLOR);
while (index != data_p->pos_tail) {
if (data_p->length > 1) {
index = (index == 0) ? CUBE_PIXELS - 1 : index - 1;
Cube_Set_Pixel(data_p->body[index].z, data_p->body[index].x, data_p->body[index].y, SNAKE_BODY_COLOR);
}
}
 
// Determine the next direction to take
Snake_Update_Direction(data_p->last_direction, 0x0);
 
// If we ate a candy, delay for a bit to rest
if (om_nom_nom) {
// Increase the level by one, show on controller if necessary
data_p->level += 1;
if (data_p->level % SNAKE_LEVEL_STEP == 0) {
uint8_t tier = data_p->level / SNAKE_LEVEL_STEP;
Controller_Set_Leds(tier, tier);
}
// Decrease the delay between frame updates by 5ms
data_p->delay -= 5;
// Clear the watchdog timer to prevent resets in a middle of a game
ClearWDT();
}
}
 
SNAKE_POINT Snake_Generate_Candy(void) {
// Generates a random position within the cube that doesnt overlap anything
SNAKE_POINT ret;
uint32_t x, y, z, brk = 0;
while(1) {
x = rand() % 8;
y = rand() % 8;
z = rand() % 8;
 
if (data_p->length != 1) {
uint32_t pos = data_p->pos_tail;
uint32_t overlap = 0;
// Iterate through the frame till we finish or find an overlap
while (pos != data_p->pos_head) {
if (data_p->body[pos].x == x &&
data_p->body[pos].y == y &&
data_p->body[pos].z == z) {
overlap = 1;
break;
} else {
pos = (pos == CUBE_PIXELS - 1) ? 0 : pos + 1;
}
}
if (!overlap)
brk = 1;
} else {
uint32_t pos = data_p->pos_tail;
if (data_p->body[pos].x != x &&
data_p->body[pos].y != y &&
data_p->body[pos].z != z) {
brk = 1;
}
}
 
if (brk)
break;
}
 
ret.x = x;
ret.y = y;
ret.z = z;
return ret;
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/SNAKE.h
0,0 → 1,52
#ifndef SNAKE_H
#define SNAKE_H
 
#include "CUBE.h"
 
#define SNAKE_BODY_COLOR BLUE
#define SNAKE_HEAD_COLOR RED
#define SNAKE_CANDY_COLOR GREEN
#define SNAKE_COLLISION_COLOR ORANGE
 
#define SNAKE_LEVEL_STEP 10
 
typedef struct {
unsigned x :8;
unsigned y :8;
unsigned z :8;
unsigned :8;
} SNAKE_POINT;
 
typedef union {
struct {
unsigned up :1;
unsigned down :1;
unsigned left :1;
unsigned backward :1;
unsigned right :1;
unsigned forward :1;
unsigned :2;
};
uint8_t value;
} SNAKE_DIRECTION;
 
typedef struct {
SNAKE_POINT body[CUBE_PIXELS];
SNAKE_POINT direction;
SNAKE_POINT candy_loc;
uint8_t last_direction;
uint32_t pos_head;
uint32_t pos_tail;
uint32_t length;
uint32_t level;
uint32_t delay;
} SNAKE_DATA;
 
void Snake_Init(SNAKE_DATA *data);
void Snake_Main(void);
void Snake_Update_Direction(uint8_t p1, uint8_t p2);
void Snake_Update_Frame(void);
SNAKE_POINT Snake_Generate_Candy(void);
 
#endif /* SNAKE_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/TRON.h
0,0 → 1,64
#ifndef TRON_H
#define TRON_H
 
#include "CUBE.h"
 
#define TRON_PLAYER_1_COLOR GREEN
#define TRON_PLAYER_2_COLOR PURPLE
#define TRON_PLAYER_1_HEAD BLUE
#define TRON_PLAYER_2_HEAD RED
#define TRON_COLLISION ORANGE
 
typedef struct {
unsigned x :8;
unsigned y :8;
unsigned z :8;
unsigned :8;
} TRON_POINT;
 
typedef union {
struct {
unsigned up :1;
unsigned down :1;
unsigned right :1;
unsigned forward :1;
unsigned left :1;
unsigned backward :1;
unsigned :2;
};
uint8_t value;
} TRON_P1_DIRECTION;
 
typedef union {
struct {
unsigned up :1;
unsigned down :1;
unsigned left :1;
unsigned backward :1;
unsigned right :1;
unsigned forward :1;
unsigned :2;
};
uint8_t value;
} TRON_P2_DIRECTION;
 
typedef struct {
TRON_POINT p1_body[CUBE_PIXELS];
TRON_POINT p1_direction;
uint8_t p1_last_direction;
 
TRON_POINT p2_body[CUBE_PIXELS];
TRON_POINT p2_direction;
uint8_t p2_last_direction;
uint32_t length;
uint32_t delay;
} TRON_DATA;
 
void Tron_Init(TRON_DATA *data);
void Tron_Main(void);
void Tron_Update_Direction(uint8_t p1, uint8_t p2);
void Tron_Update_Frame(void);
 
#endif /* TRON_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/I2C1.c
0,0 → 1,460
#include "defines.h"
#include "I2C1.h"
 
static I2C1_DATA *i2c_data_p;
 
// Initialize the data structures, should be called once before any I2C routines are called
void I2C1_Init(I2C1_DATA *data, uint8_t speed, uint8_t address) {
i2c_data_p = data;
 
i2c_data_p->buffer_in_len = 0;
i2c_data_p->buffer_in_read_ind = 0;
i2c_data_p->buffer_in_write_ind = 0;
 
i2c_data_p->buffer_out_ind = 0;
i2c_data_p->buffer_out_len = 0;
 
i2c_data_p->operating_state = I2C1_IDLE;
i2c_data_p->return_status = 0;
 
i2c_data_p->slave_in_last_byte = 0;
i2c_data_p->slave_sending_data = 0;
 
i2c_data_p->master_dest_addr = 0;
i2c_data_p->master_status = I2C1_MASTER_IDLE;
 
INTDisableInterrupts();
 
// Enable the I2C module and set the clock stretch enable bit
// Note: Automatically overrides any other pin settings
I2C1CONSET = 0x00008040;
I2C1ADD = address;
if (!speed) I2C1BRG = 0x05A; // Operate at 400kHZ (80MHz)
else I2C1BRG = 0x186; // Operate at 100kHZ (80MHz)
IFS0CLR = 0xE0000000; // Clear any existing events
IPC6CLR = 0x00001F00; // Reset priority levels
IPC6SET = 0x00001500; // Set IPL=5, Subpriority 1
IEC0SET = 0xE0000000; // Enable I2C1 interrupts
 
INTEnableInterrupts();
}
 
// Sends length number of bytes in msg to specified address (no R/W bit)
// Will return status I2C1_SEND_OK or I2C1_SEND_FAIL
void I2C1_Master_Send(uint8_t address, uint8_t *msg, uint32_t length) {
uint32_t i;
if (length == 0)
return;
 
// Copy message to send into buffer and save length/address
for (i = 0; i < length; i++) {
i2c_data_p->buffer_in[i] = msg[i];
}
i2c_data_p->buffer_in_len = length;
i2c_data_p->master_dest_addr = address;
i2c_data_p->buffer_in_read_ind = 0;
i2c_data_p->buffer_in_write_ind = 0;
 
// Change status to 'next' operation
i2c_data_p->operating_state = I2C1_SEND_ADDR;
i2c_data_p->master_status = I2C1_MASTER_SEND;
 
// Generate start condition
I2C1CONbits.SEN = 1;
}
 
// Reads length number of bytes from address (no R/W bit)
// Will return status I2C1_RECV_OK or I2C1_RECV_FAIL
void I2C1_Master_Recv(uint8_t address, uint32_t length) {
if (length == 0)
return;
 
// Save length and address to get data from
i2c_data_p->buffer_in_len = length;
i2c_data_p->master_dest_addr = address;
i2c_data_p->buffer_in_read_ind = 0;
i2c_data_p->buffer_in_write_ind = 0;
 
// Change status to 'next' operation
i2c_data_p->operating_state = I2C1_SEND_ADDR;
i2c_data_p->master_status = I2C1_MASTER_RECV;
 
// Generate start condition
I2C1CONbits.SEN = 1;
}
 
// Writes msg to address then reads length number of bytes from address
// Will return status I2C1_SEND_FAIL or I2C1_RECV_FAIL or I2C1_RECV_OK
void I2C1_Master_Restart(uint8_t address, uint8_t msg, uint32_t length) {
uint8_t c;
if (length == 0) {
c = msg;
I2C1_Master_Send(address, &c, 1);
return;
}
 
// Save length and address to get data from
i2c_data_p->buffer_in[0] = msg;
i2c_data_p->buffer_in_len = length;
i2c_data_p->master_dest_addr = address;
i2c_data_p->buffer_in_read_ind = 0;
i2c_data_p->buffer_in_write_ind = 0;
 
// Change status to 'next' operation
i2c_data_p->operating_state = I2C1_SEND_ADDR;
i2c_data_p->master_status = I2C1_MASTER_RESTART;
 
// Generate start condition
I2C1CONbits.SEN = 1;
}
 
void __ISR(_I2C_1_VECTOR, ipl5) __I2C_1_Interrupt_Handler(void) {
// Bus collision event
if (IFS0bits.I2C1BIF) {
// TODO: Handle bus collision events here
IFS0CLR = 0x20000000;
}
// Slave event
if (IFS0bits.I2C1SIF) {
I2C1_Interrupt_Slave();
IFS0CLR = 0x40000000;
}
// Master event
if (IFS0bits.I2C1MIF) {
I2C1_Interrupt_Master();
IFS0CLR = 0x80000000;
}
}
 
// An internal subroutine used in the master version of the i2c_interrupt_handler
void I2C1_Interrupt_Master() {
 
/* The PIC32 family has different master interrupts than the PIC8 family
* Master mode operations that generate a slave interrupt are:
* 1. Start condition
* 2. Repeated start sequence
* 3. Stop condition
* 4. Data transfer byte received
* 5. During a send ACK or NACK sequence to slave
* 6. Data transfer byte transmitted
* 7. During a slave-detected stop
*/
 
if (I2C1STATbits.IWCOL == 1) {
// TODO: Handle write collisions
I2C1STATbits.IWCOL = 0;
}
 
// If we are in the middle of sending data
if (i2c_data_p->master_status == I2C1_MASTER_SEND) {
switch (i2c_data_p->operating_state) {
case I2C1_IDLE:
break;
case I2C1_SEND_ADDR:
// Send the address with read bit set
i2c_data_p->operating_state = I2C1_CHECK_ACK_SEND;
I2C1TRN = (i2c_data_p->master_dest_addr << 1) | 0x0;
break;
case I2C1_CHECK_ACK_SEND:
// Check if ACK is received or not
if (!I2C1STATbits.ACKSTAT) {
// If an ACK is received, send next byte of data
if (i2c_data_p->buffer_in_read_ind < i2c_data_p->buffer_in_len) {
I2C1TRN = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
i2c_data_p->buffer_in_read_ind++;
} else {
// If no more data is to be sent, send stop bit
i2c_data_p->operating_state = I2C1_STOPPED;
I2C1CONbits.PEN = 1;
i2c_data_p->return_status = I2C1_SEND_OK;
}
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C1_STOPPED;
I2C1CONbits.PEN = 1;
i2c_data_p->return_status = I2C1_SEND_FAIL;
}
break;
case I2C1_STOPPED:
i2c_data_p->operating_state = I2C1_IDLE;
i2c_data_p->master_status = I2C1_MASTER_IDLE;
break;
}
// If we are in the middle of receiving data
} else if (i2c_data_p->master_status == I2C1_MASTER_RECV) {
switch (i2c_data_p->operating_state) {
case I2C1_IDLE:
break;
case I2C1_SEND_ADDR:
// Send address with write bit set
i2c_data_p->operating_state = I2C1_CHECK_ACK_RECV;
I2C1TRN = (i2c_data_p->master_dest_addr << 1) | 0x1;
break;
case I2C1_CHECK_ACK_RECV:
// Check if ACK is received
if (!I2C1STATbits.ACKSTAT) {
// If an ACK is received, set module to receive 1 byte of data
i2c_data_p->operating_state = I2C1_RCV_DATA;
I2C1CONbits.RCEN = 1;
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C1_STOPPED;
I2C1CONbits.PEN = 1;
i2c_data_p->return_status = I2C1_RECV_FAIL;
}
break;
case I2C1_RCV_DATA:
// On receive, save byte into buffer
// TODO: Handle possible I2C buffer overflow
i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = I2C1RCV;
i2c_data_p->buffer_in_write_ind++;
if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
// If we still need to read, send an ACK to the slave
i2c_data_p->operating_state = I2C1_REQ_DATA;
I2C1CONbits.ACKDT = 0; // ACK
I2C1CONbits.ACKEN = 1;
} else {
// If we are done reading, send an NACK to the slave
i2c_data_p->operating_state = I2C1_SEND_STOP;
I2C1CONbits.ACKDT = 1; // NACK
I2C1CONbits.ACKEN = 1;
}
break;
case I2C1_REQ_DATA:
// Set module to receive one byte of data
i2c_data_p->operating_state = I2C1_RCV_DATA;
I2C1CONbits.RCEN = 1;
break;
case I2C1_SEND_STOP:
// Send the stop bit
i2c_data_p->operating_state = I2C1_STOPPED;
I2C1CONbits.PEN = 1;
i2c_data_p->return_status = I2C1_RECV_OK;
break;
case I2C1_STOPPED:
i2c_data_p->operating_state = I2C1_IDLE;
i2c_data_p->master_status = I2C1_MASTER_IDLE;
break;
}
} else if (i2c_data_p->master_status == I2C1_MASTER_RESTART) {
switch (i2c_data_p->operating_state) {
case I2C1_IDLE:
break;
case I2C1_SEND_ADDR:
// Send the address with read bit set
i2c_data_p->operating_state = I2C1_CHECK_ACK_SEND;
I2C1TRN = (i2c_data_p->master_dest_addr << 1) | 0x0;
break;
case I2C1_CHECK_ACK_SEND:
// Check if ACK is received or not
if (!I2C1STATbits.ACKSTAT) {
// If an ACK is received, send first byte of data
I2C1TRN = i2c_data_p->buffer_in[0];
i2c_data_p->operating_state = I2C1_CHECK_ACK_RESTART;
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C1_STOPPED;
I2C1CONbits.PEN = 1;
i2c_data_p->return_status = I2C1_SEND_FAIL;
}
break;
case I2C1_CHECK_ACK_RESTART:
if (!I2C1STATbits.ACKSTAT) {
I2C1CONbits.RSEN = 1;
i2c_data_p->operating_state = I2C1_SEND_ADDR_2;
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C1_STOPPED;
I2C1CONbits.PEN = 1;
i2c_data_p->return_status = I2C1_SEND_FAIL;
}
break;
case I2C1_SEND_ADDR_2:
// Send the address with read bit set
i2c_data_p->operating_state = I2C1_CHECK_ACK_RECV;
I2C1TRN = (i2c_data_p->master_dest_addr << 1) | 0x1;
break;
case I2C1_CHECK_ACK_RECV:
// Check if ACK is received
if (!I2C1STATbits.ACKSTAT) {
// If an ACK is received, set module to receive 1 byte of data
i2c_data_p->operating_state = I2C1_RCV_DATA;
I2C1CONbits.RCEN = 1;
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C1_STOPPED;
I2C1CONbits.PEN = 1;
i2c_data_p->return_status = I2C1_RECV_FAIL;
}
break;
case I2C1_RCV_DATA:
// On receive, save byte into buffer
// TODO: Handle possible I2C buffer overflow
i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = I2C1RCV;
i2c_data_p->buffer_in_write_ind++;
if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
// If we still need to read, send an ACK to the slave
i2c_data_p->operating_state = I2C1_REQ_DATA;
I2C1CONbits.ACKDT = 0; // ACK
I2C1CONbits.ACKEN = 1;
} else {
// If we are done reading, send an NACK to the slave
i2c_data_p->operating_state = I2C1_SEND_STOP;
I2C1CONbits.ACKDT = 1; // NACK
I2C1CONbits.ACKEN = 1;
}
break;
case I2C1_REQ_DATA:
// Set module to receive one byte of data
i2c_data_p->operating_state = I2C1_RCV_DATA;
I2C1CONbits.RCEN = 1;
break;
case I2C1_SEND_STOP:
// Send the stop bit
i2c_data_p->operating_state = I2C1_STOPPED;
I2C1CONbits.PEN = 1;
i2c_data_p->return_status = I2C1_RECV_OK;
break;
case I2C1_STOPPED:
i2c_data_p->operating_state = I2C1_IDLE;
i2c_data_p->master_status = I2C1_MASTER_IDLE;
break;
}
}
}
 
void I2C1_Interrupt_Slave() {
// !!WARNING!! THIS CODE DOES -NOT- HAVE ANY ERROR HANDLING !!
// TODO: Add error handling to this interrupt function
 
/* The PIC32 family has different slave interrupts than the PIC8 family
* Slave mode operations that generate a slave interrupt are:
* 1. Detection of a valid device address (including general call)
* 2. Reception of data
* 3. Request to transmit data
*/
 
uint8_t received_data;
uint8_t data_read_from_buffer = 0;
uint8_t data_written_to_buffer = 0;
uint8_t overrun_error = 0;
 
// Clear SSPOV (overflow bit)
if (I2C1STATbits.I2COV == 1) {
I2C1STATbits.I2COV = 0;
overrun_error = 1;
i2c_data_p->return_status = I2C1_ERR_OVERRUN;
}
 
// Read SPPxBUF if it is full
if (I2C1STATbits.RBF == 1) {
received_data = I2C1RCV;
data_read_from_buffer = 1;
}
 
if (!overrun_error) {
if (I2C1STATbits.R_W == 0) {
// Slave is receiving data
i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = received_data;
if (i2c_data_p->buffer_in_write_ind == MAXI2C1BUF - 1) {
i2c_data_p->buffer_in_write_ind = 0;
} else {
i2c_data_p->buffer_in_write_ind++;
}
if (i2c_data_p->buffer_in_len < MAXI2C1BUF - 1) {
i2c_data_p->buffer_in_len++;
}
i2c_data_p->slave_in_last_byte = received_data;
i2c_data_p->return_status = I2C1_RECV_OK;
} else {
// Slave is returning data
if (!i2c_data_p->slave_sending_data) {
// If we are not currently sending data, figure out what to reply with
if (I2C1_Process_Request(i2c_data_p->slave_in_last_byte)) {
// Data exists to be returned, send first byte
I2C1TRN = i2c_data_p->buffer_out[0];
data_written_to_buffer = 1;
i2c_data_p->buffer_out_ind = 1;
i2c_data_p->slave_sending_data = 1;
} else {
// Unknown request, fill rest of request with 0s
I2C1TRN = 0x0;
data_written_to_buffer = 1;
i2c_data_p->slave_sending_data = 0;
i2c_data_p->return_status = I2C1_SEND_FAIL;
}
} else {
// Sending remaining data back to master
if (i2c_data_p->buffer_out_ind < i2c_data_p->buffer_out_len) {
I2C1TRN = i2c_data_p->buffer_out[i2c_data_p->buffer_out_ind];
data_written_to_buffer = 1;
i2c_data_p->buffer_out_ind++;
} else {
// Nothing left to send, fill rest of request with 0s
I2C1TRN = 0x0;
data_written_to_buffer = 1;
i2c_data_p->slave_sending_data = 0;
i2c_data_p->return_status = I2C1_SEND_OK;
}
}
}
}
 
// Release the clock stretching bit (if we should)
if (data_read_from_buffer || data_written_to_buffer) {
// Release the clock
if (I2C1CONbits.SCLREL == 0) {
I2C1CONbits.SCLREL = 1;
}
}
}
 
/* Returns 0 if I2C module is currently busy, otherwise returns status code */
uint8_t I2C1_Get_Status() {
if (i2c_data_p->master_status == I2C1_MASTER_IDLE &&
i2c_data_p->operating_state == I2C1_IDLE &&
I2C1STATbits.TBF == 0) {
return i2c_data_p->return_status;
} else {
return 0;
}
}
 
uint8_t I2C1_Buffer_Len() {
return i2c_data_p->buffer_in_len;
}
 
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
uint8_t I2C1_Read_Buffer(uint8_t *buffer) {
uint32_t i = 0;
while (i2c_data_p->buffer_in_len != 0) {
buffer[i] = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
i++;
if (i2c_data_p->buffer_in_read_ind == MAXI2C1BUF-1) {
i2c_data_p->buffer_in_read_ind = 0;
} else {
i2c_data_p->buffer_in_read_ind++;
}
i2c_data_p->buffer_in_len--;
}
return i;
}
 
/* Put data to be returned here */
uint8_t I2C1_Process_Request(uint8_t c) {
uint8_t ret = 0;
switch (c) {
case 0x01:
i2c_data_p->buffer_out[0] = 0x12;
i2c_data_p->buffer_out_len = 1;
ret = 1;
break;
case 0x02:
i2c_data_p->buffer_out[0] = 0x34;
i2c_data_p->buffer_out[1] = 0x56;
i2c_data_p->buffer_out_len = 2;
ret = 1;
break;
}
return ret;
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/TIMER4.h
0,0 → 1,17
#ifndef TIMER4_H
#define TIMER4_H
 
typedef struct {
void (*callback_function_1)(void);
void (*callback_function_2)(void);
uint32_t divider;
uint32_t count;
} TIMER4_DATA;
 
void TIMER4_Init(TIMER4_DATA *data, void (*callback_ms)(void),
void (*callback_div)(void), uint32_t time_ms);
void TIMER4_Start(void);
void TIMER4_Stop(void);
 
#endif /* TIMER4_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/TIMER5.c
0,0 → 1,55
#include "defines.h"
#include "TIMER5.h"
 
static TIMER5_DATA *timer_data_ptr;
 
void TIMER5_Init(TIMER5_DATA *data, void (*callback)(void), uint32_t time_us) {
if (data != NULL) // if ptr is null, use existing data
timer_data_ptr = data;
 
timer_data_ptr->callback_function = callback;
 
INTDisableInterrupts();
 
T5CON = 0x0;
 
// PR5 is 16 bits wide, so we need to determine what pre-scaler to use
uint16_t time;
if (time_us < 13107) {
time = 5 * time_us;
T5CONSET = 0x0040; // Prescaler at 1:16
} else if (time_us < 26214) {
time = 2.5 * time_us;
T5CONSET = 0x0050; // Prescaler at 1:32
} else if (time_us < 52428) {
time = 1.25 * time_us;
T5CONSET = 0x0060; // Prescaler at 1:64
} else { // Maximum time_us of 209712
time = 0.3125 * time_us;
T5CONSET = 0x0070; // Prescaler at 1:256
}
 
Nop();
TMR5 = 0x0; // Clear timer register
PR5 = time; // Load period register
IPC5SET = 0x0000000D; // Set priority level = 3, sub-priority level = 1
IFS0CLR = 0x00100000; // Clear timer interrupt flag
IEC0SET = 0x00100000; // Enable timer interrupt
 
INTEnableInterrupts();
}
 
void TIMER5_Start(void) {
T5CONSET = 0x8000; // Start timer
}
 
void TIMER5_Stop(void) {
T5CONCLR = 0x8000; // Stop timer
}
 
void __ISR(_TIMER_5_VECTOR, ipl4) __TIMER_5_Interrupt_Handler(void) {
// Call the saved callback function
(*timer_data_ptr->callback_function)();
 
IFS0CLR = 0x00100000; // Clear the timer interrupt flag
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/I2C1.h
0,0 → 1,78
#ifndef I2C1_H
#define I2C1_H
 
#define MAXI2C1BUF 32
 
// I2C Operating Speed
#define I2C1_400KHZ 0x0
#define I2C1_100KHZ 0x1
 
// Operating State
#define I2C1_IDLE 0x1
//#define I2C1_STARTED 0x2
#define I2C1_RCV_DATA 0x3
//#define I2C1_SEND_DATA 0x4
#define I2C1_SEND_ADDR 0x5
#define I2C1_SEND_ADDR_2 0x6
#define I2C1_CHECK_ACK_SEND 0x7
#define I2C1_CHECK_ACK_RECV 0x8
#define I2C1_CHECK_ACK_RESTART 0x9
#define I2C1_REQ_DATA 0xA
#define I2C1_SEND_STOP 0xB
//#define I2C1_SEND_START 0xC
#define I2C1_STOPPED 0xD
 
// Operating Mode
#define I2C1_MODE_SLAVE 0x10
#define I2C1_MODE_MASTER 0x11
 
// Master Status
#define I2C1_MASTER_SEND 0x20
#define I2C1_MASTER_RECV 0x21
#define I2C1_MASTER_RESTART 0x22
#define I2C1_MASTER_IDLE 0x23
 
// Return Status
#define I2C1_SEND_OK 0x30
#define I2C1_SEND_FAIL 0x31
#define I2C1_RECV_OK 0x32
#define I2C1_RECV_FAIL 0x33
#define I2C1_DATA_AVAL 0x34
#define I2C1_ERR_NOADDR 0x35
#define I2C1_ERR_OVERRUN 0x36
#define I2C1_ERR_NODATA 0x37
#define I2C1_ERR_BUFFER_OVERRUN 0x38
 
typedef struct {
uint8_t buffer_in[MAXI2C1BUF];
uint32_t buffer_in_len;
uint32_t buffer_in_read_ind;
uint32_t buffer_in_write_ind;
 
uint8_t buffer_out[MAXI2C1BUF];
uint32_t buffer_out_len;
uint32_t buffer_out_ind;
 
uint8_t operating_state;
uint8_t return_status;
 
uint8_t master_dest_addr;
uint8_t master_status;
 
uint8_t slave_in_last_byte;
uint8_t slave_sending_data;
} I2C1_DATA;
 
void I2C1_Init(I2C1_DATA *data, uint8_t speed, uint8_t address);
void I2C1_Master_Send(uint8_t address, uint8_t *msg, uint32_t length);
void I2C1_Master_Recv(uint8_t address, uint32_t length);
void I2C1_Master_Restart(uint8_t address, uint8_t msg, uint32_t length);
void I2C1_Interrupt_Master(void);
void I2C1_Interrupt_Slave(void);
uint8_t I2C1_Get_Status(void);
uint8_t I2C1_Buffer_Len(void);
uint8_t I2C1_Read_Buffer(uint8_t *buffer);
uint8_t I2C1_Process_Request(uint8_t);
 
#endif /* I2C1_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/UART1.c
0,0 → 1,105
#include "defines.h"
#include "UART1.h"
 
static UART1_DATA *uart_data_ptr;
 
/* Note: BRGH values are different from PIC18!
*
* Baud Rate Calculation (BRGH = 0):
* Baud Rate = PerfBusFreq / (16 * (BRG + 1))
* BRG = PerfBusFreq / (16 * Baud Rate) - 1
*
* Baud Rate Calculation (BRGH = 1):
* Baud Rate = PerfBusFreq / (4 * (BRG + 1))
* BRG = PerfBusFreq / (4 * Baud Rate) - 1
*/
 
void UART1_Init(UART1_DATA *data, void (*rx_callback)(uint8_t)) {
uart_data_ptr = data;
uart_data_ptr->rx_callback = rx_callback;
uart_data_ptr->buffer_out_len = 0;
uart_data_ptr->buffer_out_ind = 0;
 
INTDisableInterrupts();
 
IEC0CLR = 0x1C000000; // Disable all UART1 interrupts
IFS0CLR = 0x1C000000; // Clear any existing events
IPC6SET = 0x00000009; // Set Priority = 2, Subpriority = 1
U1MODE = 0x00008008; // UART enabled, BRGH = 1
U1STA = 0x00009400; // TX interrupt on buffer empty, RX interrupt on buffer not empty
 
// U1BRG = 173; // Set baud rate to 115200 @ 80MHz (0.22% error)
U1BRG = 86; // Set baud rate to 230400 @ 80MHz (0.22% error)
// U1BRG = 77; // Set baud rate to 256000 @ 80MHz (0.12% error)
// U1BRG = 42; // Set baud rate to 460800 @ 80MHz (0.94% error)
// U1BRG = 21; // Set baud rate to 921600 @ 80MHz (1.36% error)
IEC0SET = 0x0C000000; // Enable the RX and Error interrupts
 
INTEnableInterrupts();
}
 
uint8_t UART1_Write(uint8_t *string, uint32_t length) {
if (length > UART1_BUFFER_SIZE)
return 0;
if (uart_data_ptr->buffer_out_len != 0)
return 0;
 
// Put the data to send into the outbound buffer
uart_data_ptr->buffer_out_len = length;
uart_data_ptr->buffer_out_ind = 0;
uint8_t i;
for (i = 0; i < length; i++) {
uart_data_ptr->buffer_out[i] = string[i];
}
IEC0SET = 0x10000000; // Enable TX interrupt
return 1;
}
 
void __ISR(_UART_1_VECTOR, ipl2) __UART_1_Interrupt_Handler(void) {
// Process UART1 error flag
if (IFS0bits.U1EIF) {
if (U1STAbits.PERR) { // Process parity error
 
}
if (U1STAbits.FERR) { // Process frame error
 
}
if (U1STAbits.OERR) { // Process receive buffer overrun error
U1STAbits.OERR = 0; // Clear the overrun error if set
}
IFS0CLR = 0x04000000; // Clear the error flag
}
 
// Process UART1 recieve flag
if (IFS0bits.U1RXIF) {
// Read the data received from the last transfer
while (U1STAbits.URXDA) {
uint8_t c = U1RXREG;
// Call the RX callback function on each received data
if (uart_data_ptr->rx_callback != NULL) {
(*uart_data_ptr->rx_callback)(c);
}
}
IFS0CLR = 0x08000000; // Clear the recieve flag
}
 
// Process UART1 transmit flag
if (IFS0bits.U1TXIF && IEC0bits.U1TXIE) {
// Disable the transmit interrupt if all data has been sent
if (uart_data_ptr->buffer_out_ind == uart_data_ptr->buffer_out_len) {
IEC0CLR = 0x10000000;
uart_data_ptr->buffer_out_len = 0;
} else {
// Start filling the transmit buffer
while (!U1STAbits.UTXBF) {
U1TXREG = uart_data_ptr->buffer_out[uart_data_ptr->buffer_out_ind];
uart_data_ptr->buffer_out_ind++;
if (uart_data_ptr->buffer_out_ind == uart_data_ptr->buffer_out_len)
break;
}
}
IFS0CLR = 0x10000000; // Clear the transmit flag
}
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/BTN.c
0,0 → 1,61
#include "defines.h"
#include "BTN.h"
 
static BTN_DATA *btn_data_ptr;
 
void BTN_Init(BTN_DATA *data, void (*callback_1)(void), void (*callback_2)(void), void (*callback_3)(void)) {
btn_data_ptr = data;
btn_data_ptr->callback_function_1 = callback_1;
btn_data_ptr->callback_function_2 = callback_2;
btn_data_ptr->callback_function_3 = callback_3;
 
BTN1_TRIS = 1;
BTN2_TRIS = 1;
BTN3_TRIS = 1;
 
INTDisableInterrupts();
CNCONSET = 0x8000; // Turn on change notice interrupt
#if defined CEREBOT_32MX7
CNENSET = 0x80300; // Set interrupt on CN8/9/19
#elif defined CEREBOT_MX7CK
CNENSET = 0x00300; // Set interrupt on CN8/9
#endif
int32_t tmp = BTN1_PORT;
tmp = BTN2_PORT;
tmp = BTN3_PORT;
IPC6SET = 0xD0000; // Set priority level = 3, sub-priority level = 1
IFS1CLR = 0x1; // Clear interrupt flag
IEC1SET = 0x1; // Enable interrupt
 
INTEnableInterrupts();
}
 
void __ISR(_CHANGE_NOTICE_VECTOR, ipl3) __CN_Interrupt_Handler(void) {
// Upon interrupt, debounce input and call saved function
if (BTN1_PORT == 1) {
Delay_MS(BTN_DEBOUNCE_MS);
if (BTN1_PORT == 1) {
if (btn_data_ptr->callback_function_1 != NULL)
(*btn_data_ptr->callback_function_1)();
}
}
if (BTN2_PORT == 1) {
Delay_MS(BTN_DEBOUNCE_MS);
if (BTN2_PORT == 1) {
if (btn_data_ptr->callback_function_2 != NULL)
(*btn_data_ptr->callback_function_2)();
}
}
#ifdef CEREBOT_32MX7
if (BTN3_PORT == 1) {
Delay_MS(BTN_DEBOUNCE_MS);
if (BTN3_PORT == 1) {
if (btn_data_ptr->callback_function_3 != NULL)
(*btn_data_ptr->callback_function_3)();
}
}
#endif
IFS1CLR = 0x1; // Clear interrupt flag
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/PWM2.c
0,0 → 1,21
#include "defines.h"
#include "PWM2.h"
 
void PWM2_Init(void) {
OC2CON = 0x0000;
OC2R = 0x0001; // PWM initial duty cycle
OC2RS = 0x0001; // PWM duty cycle
OC2CON = 0x0006; // PWM off, 16-bit, timer 2, fault pin disabled
 
IFS0CLR = 0x00000100; // Disable Timer 2 interrupt
T2CONSET = 0x8000; // Turn on Timer 2
PR2 = 0x0003; // PWM period ~ 16-20Mhz
}
 
void PWM2_Start(void) {
OC2CONSET = 0x8000;
}
 
void PWM2_Stop(void) {
OC2CONCLR = 0x8000;
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/SPI1.c
0,0 → 1,118
#include "defines.h"
#include "SPI1.h"
 
static SPI1_DATA *spi_data_ptr;
 
void SPI1_Init(SPI1_DATA *data, void (*rx_callback)(uint8_t)) {
spi_data_ptr = data;
spi_data_ptr->buffer_out_ind = 0;
spi_data_ptr->buffer_out_len = 0;
spi_data_ptr->rx_callback = rx_callback;
INTDisableInterrupts();
 
// Note: FIFO enhanced buffer depth is 4/8/16 for 32/16/8 bit widths
// Alternative Configuration:
// The third value is the SPI bitrate which is 1/2 the frequency of the
// desired clock frequency. Thus 40Mhz / (20Mhz / 2) = 4.
// Note: SPI_OPEN_TBE_NOT_FULL should only be used at >10Mhz speeds
// SpiChnOpen(SPI_CHANNEL1, SPI_OPEN_MSTEN | SPI_OPEN_ENHBUF | SPI_OPEN_TBE_NOT_FULL | SPI_OPEN_RBF_NOT_EMPTY, 4);
// INTSetVectorPriority(INT_SPI_1_VECTOR, INT_PRIORITY_LEVEL_6);
// INTSetVectorSubPriority(INT_SPI_1_VECTOR, INT_SUB_PRIORITY_LEVEL_1);
// INTClearFlag(INT_SPI1E);
// INTClearFlag(INT_SPI1TX);
// INTClearFlag(INT_SPI1RX);
 
// FSCK = FPB / (2 * (SPIxBRG + 1))
IEC0CLR = 0x03800000; // Disable all SPI interrupts
SPI1CON = 0; // Stops and resets the SPI1.
uint32_t tmp = SPI1BUF; // Clears the receive buffer
IFS0CLR = 0x03800000; // Clear any existing event
IPC5CLR = 0x1F000000; // Clear the priority
IPC5SET = 0x19000000; // Set IPL=6, Subpriority 1
SPI1BRG = 0x1; // Use FPB/4 clock frequency
SPI1STATCLR = 0x40; // Clear the Overflow
#ifndef SPI_WRITE_ONLY
IEC0SET = 0x01800000; // Enable RX and Error interrupts
#endif
// Enhanced buffer, SPI on, 8 bits transfer, SMP=1, Master mode
// SPIxTXIF set on buffer empty, SPIxRXIF set on buffer not empty
SPI1CON = 0x18225;
 
INTEnableInterrupts();
}
 
uint8_t SPI1_Write(uint8_t *array, uint32_t length, void (*tx_callback)(void)) {
spi_data_ptr->tx_callback = tx_callback;
 
if (length > SPI1_BUFFER_OUT_SIZE)
return 0;
if (spi_data_ptr->buffer_out_len != 0)
return 0;
 
// Put the data to send into the outbound buffer
spi_data_ptr->buffer_out_len = length;
spi_data_ptr->buffer_out_ind = length-1;
int32_t i;
for (i = 0; i < length; i++) {
spi_data_ptr->buffer_out[i] = array[i];
}
IEC0SET = 0x02000000; // Enable TX interrupt
return 1;
}
 
void __ISR(_SPI_1_VECTOR, ipl6) __SPI_1_Interrupt_Handler(void) {
#ifndef SPI_WRITE_ONLY
// Process SPI1 error flag
if (IFS0bits.SPI1EIF) {
// Clear the receive overflow bit if it is set
if (SPI1STATbits.SPIROV) {
SPI1STATbits.SPIROV = 0;
}
IFS0CLR = 0x00800000; // Clear the error flag
}
 
// Process SPI1 receive flag
if (IFS0bits.SPI1RXIF) {
int32_t i;
// Read the data received from the last transfer
int32_t rxBufferCount = SPI1STATbits.RXBUFELM;
for (i = 0; i < rxBufferCount; i++) {
int8_t c = SPI1BUF;
// Call the RX callback function on the received data
if (spi_data_ptr->rx_callback != NULL)
(*spi_data_ptr->rx_callback)(c);
}
IFS0CLR = 0x01000000; // Clear the RX flag
}
#endif
 
// Process SPI1 transmit flag
if (IFS0bits.SPI1TXIF && IEC0bits.SPI1TXIE) {
int32_t i;
// Disable the transmit interrupt if all data has been sent
if (spi_data_ptr->buffer_out_len == 0) {
IEC0CLR=0x02000000;
if (spi_data_ptr->tx_callback != NULL)
(*spi_data_ptr->tx_callback)();
} else {
// Start transmitting the data in the buffer
int32_t txBufferFree = 16 - SPI1STATbits.TXBUFELM;
if (spi_data_ptr->buffer_out_len > txBufferFree) {
for (i = 0; i < txBufferFree; i++) {
SPI1BUF = spi_data_ptr->buffer_out[spi_data_ptr->buffer_out_ind];
spi_data_ptr->buffer_out_ind--;
}
spi_data_ptr->buffer_out_len -= txBufferFree;
} else {
for (i = 0; i < spi_data_ptr->buffer_out_len; i++) {
SPI1BUF = spi_data_ptr->buffer_out[spi_data_ptr->buffer_out_ind];
spi_data_ptr->buffer_out_ind--;
}
spi_data_ptr->buffer_out_len = 0;
}
}
IFS0CLR = 0x02000000; // Clear the TX flag
}
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/SPI1.h
0,0 → 1,23
#ifndef SPI1_H
#define SPI1_H
 
#define SPI1_BUFFER_OUT_SIZE 300
//#define SPI1_BUFFER_IN_SIZE 10
 
#define SPI_WRITE_ONLY
 
typedef struct {
uint8_t buffer_out[SPI1_BUFFER_OUT_SIZE];
uint32_t buffer_out_ind;
uint32_t buffer_out_len;
 
void (*tx_callback)(void);
void (*rx_callback)(uint8_t);
} SPI1_DATA;
 
void SPI1_Init(SPI1_DATA *data, void (*rx_callback)(uint8_t));
// Note: SPI1_Write() writes MSB -> LSB!
uint8_t SPI1_Write(uint8_t *array, uint32_t length, void (*tx_callback)(void));
 
#endif /* SPI1_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/SPI4.c
0,0 → 1,151
#include "defines.h"
#include "SPI4.h"
 
static SPI4_DATA *spi_data_ptr;
 
void SPI4_Init(SPI4_DATA *data) {
spi_data_ptr = data;
spi_data_ptr->buffer_out_ind = 0;
spi_data_ptr->buffer_out_len = 0;
spi_data_ptr->buffer_in_ind = 0;
spi_data_ptr->buffer_in_len = 0;
spi_data_ptr->write_blank = 0;
 
INTDisableInterrupts();
 
// Note: FIFO enhanced buffer depth is 4/8/16 for 32/16/8 bit widths
 
// FSCK = FPB / (2 * (SPIxBRG + 1))
IEC1CLR = 0x00000700; // Disable all SPI interrupts
SPI4CON = 0; // Stops and resets the SPI4.
uint32_t tmp = SPI4BUF; // Clears the receive buffer
IFS1CLR = 0x00000700; // Clear any existing event
IPC8CLR = 0x0000001F; // Clear the priority
IPC8SET = 0x0000001A; // Set IPL=6, Subpriority 2
SPI4BRG = 0x4; // Use FPB/10 clock frequency
SPI4STATCLR = 0x40; // Clear the Overflow
IEC1SET = 0x00000300; // Enable RX and Error interrupts
 
// Enhanced buffer, SPI on, 8 bits transfer, SMP=1, Master mode
// SPIxTXIF set on buffer empty, SPIxRXIF set on buffer not empty
SPI4CON = 0x18225;
 
INTEnableInterrupts();
}
 
uint8_t SPI4_Read(uint32_t length, void (*rx_callback)(uint8_t, uint8_t *)) {
spi_data_ptr->rx_callback = rx_callback;
 
// Ensure that the receiving buffer is large enough
if (length > SPI4_BUFFER_IN_SIZE)
return 0;
// Ensure that no previous transactions are in progress
if (spi_data_ptr->buffer_in_len != 0)
return 0;
 
spi_data_ptr->write_blank = 1;
spi_data_ptr->buffer_in_len = length;
spi_data_ptr->buffer_in_ind = 0;
SPI4_Write(NULL, length, NULL);
return 1;
}
 
uint8_t SPI4_Write(uint8_t *array, uint32_t length, void (*tx_callback)(void)) {
spi_data_ptr->tx_callback = tx_callback;
 
// We only care about the transmit length if we are sending data
if (length > SPI4_BUFFER_OUT_SIZE && !spi_data_ptr->write_blank)
return 0;
 
// Ensure that no previous transactions are in progress
if (spi_data_ptr->buffer_out_len != 0)
return 0;
 
// Put the data to send into the outbound buffer
spi_data_ptr->buffer_out_len = length;
spi_data_ptr->buffer_out_ind = 0;
 
// Copy only if we are actually going to transmit data
if (!spi_data_ptr->write_blank) {
int32_t i;
for (i = 0; i < length; i++) {
spi_data_ptr->buffer_out[i] = array[i];
}
}
IEC1SET = 0x00000400; // Enable TX interrupt
return 1;
}
 
void __ISR(_SPI_4_VECTOR, ipl6) __SPI_4_Interrupt_Handler(void) {
// Process SPI4 error flag
if (IFS1bits.SPI4EIF) {
// Clear the receive overflow bit if it is set
if (SPI4STATbits.SPIROV) {
SPI4STATbits.SPIROV = 0;
}
IFS1CLR = 0x00000100; // Clear the error flag
}
 
// Process SPI4 receive flag
if (IFS1bits.SPI4RXIF) {
uint32_t i;
// Read the data received from the last transfer
uint32_t rxBufferCount = SPI4STATbits.RXBUFELM;
for (i = 0; i < rxBufferCount; i++) {
int8_t c = SPI4BUF;
// Put the received data into the buffer
if (spi_data_ptr->buffer_in_len != 0) {
spi_data_ptr->buffer_in[spi_data_ptr->buffer_in_ind] = c;
spi_data_ptr->buffer_in_ind++;
// If done acquiring requested length, reset
if (spi_data_ptr->buffer_in_ind == spi_data_ptr->buffer_in_len) {
// Call the RX callback function on the received data
if (spi_data_ptr->rx_callback != NULL)
(*spi_data_ptr->rx_callback)(spi_data_ptr->buffer_in_len, spi_data_ptr->buffer_in);
spi_data_ptr->buffer_in_len = 0;
}
}
}
IFS1CLR = 0x00000200; // Clear the RX flag
}
 
// Process SPI4 transmit flag
if (IFS1bits.SPI4TXIF && IEC1bits.SPI4TXIE) {
int32_t i;
// Disable the transmit interrupt if all data has been sent
if (spi_data_ptr->buffer_out_len == 0) {
IEC1CLR=0x00000400;
spi_data_ptr->write_blank = 0;
// Call the TX callback function at end of transmission
if (spi_data_ptr->tx_callback != NULL)
(*spi_data_ptr->tx_callback)();
} else {
// Start transmitting the data in the buffer
int32_t txBufferFree = 16 - SPI4STATbits.TXBUFELM;
if (spi_data_ptr->buffer_out_len > txBufferFree) {
for (i = 0; i < txBufferFree; i++) {
if (spi_data_ptr->write_blank) {
SPI4BUF = 0x00;
} else {
SPI4BUF = spi_data_ptr->buffer_out[spi_data_ptr->buffer_out_ind];
spi_data_ptr->buffer_out_ind++;
}
}
spi_data_ptr->buffer_out_len -= txBufferFree;
} else {
for (i = 0; i < spi_data_ptr->buffer_out_len; i++) {
if (spi_data_ptr->write_blank) {
SPI4BUF = 0x00;
} else {
SPI4BUF = spi_data_ptr->buffer_out[spi_data_ptr->buffer_out_ind];
spi_data_ptr->buffer_out_ind++;
}
}
spi_data_ptr->buffer_out_len = 0;
}
}
IFS1CLR = 0x00000400; // Clear the TX flag
}
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/SPI4.h
0,0 → 1,26
#ifndef SPI4_H
#define SPI4_H
 
#define SPI4_BUFFER_OUT_SIZE 10
#define SPI4_BUFFER_IN_SIZE 10
 
typedef struct {
uint8_t buffer_out[SPI4_BUFFER_OUT_SIZE];
uint32_t buffer_out_ind;
uint32_t buffer_out_len;
uint8_t write_blank;
 
uint8_t buffer_in[SPI4_BUFFER_IN_SIZE];
uint32_t buffer_in_ind;
uint32_t buffer_in_len;
 
void (*tx_callback)(void);
void (*rx_callback)(uint8_t, uint8_t *);
} SPI4_DATA;
 
void SPI4_Init(SPI4_DATA *data);
uint8_t SPI4_Read(uint32_t length, void (*rx_callback)(uint8_t, uint8_t *));
uint8_t SPI4_Write(uint8_t *array, uint32_t length, void (*tx_callback)(void));
 
#endif /* SPI4_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/TIMER5.h
0,0 → 1,13
#ifndef TIMER5_H
#define TIMER5_H
 
typedef struct {
void (*callback_function)(void);
} TIMER5_DATA;
 
void TIMER5_Init(TIMER5_DATA *data, void (*callback)(void), uint32_t time_us);
void TIMER5_Start(void);
void TIMER5_Stop(void);
 
#endif /* TIMER5_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/UART1.h
0,0 → 1,17
#ifndef UART1_H
#define UART1_H
 
#define UART1_BUFFER_SIZE 128
 
typedef struct {
void (*rx_callback)(uint8_t c);
 
uint8_t buffer_out[UART1_BUFFER_SIZE];
uint32_t buffer_out_ind;
uint32_t buffer_out_len;
} UART1_DATA;
 
void UART1_Init(UART1_DATA *data, void (*rx_callback)(uint8_t));
uint8_t UART1_Write(uint8_t *string, uint32_t length);
 
#endif /* UART1_H */
/PIC Stuff/Cerebot_32MX7_LED_Cube/glcdfont.h
0,0 → 1,264
#ifndef FONT5X7_H
#define FONT5X7_H
 
// Standard ASCII 5x7 font
// LSB = top of vertical line, 5 lines from left to right
 
const uint8_t font[] = {
0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
0x18, 0x3C, 0x7E, 0x3C, 0x18,
0x1C, 0x57, 0x7D, 0x57, 0x1C,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
0x00, 0x18, 0x3C, 0x18, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
0x00, 0x18, 0x24, 0x18, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
0x30, 0x48, 0x3A, 0x06, 0x0E,
0x26, 0x29, 0x79, 0x29, 0x26,
0x40, 0x7F, 0x05, 0x05, 0x07,
0x40, 0x7F, 0x05, 0x25, 0x3F,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
0x7F, 0x3E, 0x1C, 0x1C, 0x08,
0x08, 0x1C, 0x1C, 0x3E, 0x7F,
0x14, 0x22, 0x7F, 0x22, 0x14,
0x5F, 0x5F, 0x00, 0x5F, 0x5F,
0x06, 0x09, 0x7F, 0x01, 0x7F,
0x00, 0x66, 0x89, 0x95, 0x6A,
0x60, 0x60, 0x60, 0x60, 0x60,
0x94, 0xA2, 0xFF, 0xA2, 0x94,
0x08, 0x04, 0x7E, 0x04, 0x08,
0x10, 0x20, 0x7E, 0x20, 0x10,
0x08, 0x08, 0x2A, 0x1C, 0x08,
0x08, 0x1C, 0x2A, 0x08, 0x08,
0x1E, 0x10, 0x10, 0x10, 0x10,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
0x30, 0x38, 0x3E, 0x38, 0x30,
0x06, 0x0E, 0x3E, 0x0E, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14,
0x24, 0x2A, 0x7F, 0x2A, 0x12,
0x23, 0x13, 0x08, 0x64, 0x62,
0x36, 0x49, 0x56, 0x20, 0x50,
0x00, 0x08, 0x07, 0x03, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
0x08, 0x08, 0x3E, 0x08, 0x08,
0x00, 0x80, 0x70, 0x30, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x60, 0x60, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02,
0x3E, 0x51, 0x49, 0x45, 0x3E,
0x00, 0x42, 0x7F, 0x40, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46,
0x21, 0x41, 0x49, 0x4D, 0x33,
0x18, 0x14, 0x12, 0x7F, 0x10,
0x27, 0x45, 0x45, 0x45, 0x39,
0x3C, 0x4A, 0x49, 0x49, 0x31,
0x41, 0x21, 0x11, 0x09, 0x07,
0x36, 0x49, 0x49, 0x49, 0x36,
0x46, 0x49, 0x49, 0x29, 0x1E,
0x00, 0x00, 0x14, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41,
0x14, 0x14, 0x14, 0x14, 0x14,
0x00, 0x41, 0x22, 0x14, 0x08,
0x02, 0x01, 0x59, 0x09, 0x06,
0x3E, 0x41, 0x5D, 0x59, 0x4E,
0x7C, 0x12, 0x11, 0x12, 0x7C,
0x7F, 0x49, 0x49, 0x49, 0x36,
0x3E, 0x41, 0x41, 0x41, 0x22,
0x7F, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x49, 0x49, 0x49, 0x41,
0x7F, 0x09, 0x09, 0x09, 0x01,
0x3E, 0x41, 0x41, 0x51, 0x73,
0x7F, 0x08, 0x08, 0x08, 0x7F,
0x00, 0x41, 0x7F, 0x41, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01,
0x7F, 0x08, 0x14, 0x22, 0x41,
0x7F, 0x40, 0x40, 0x40, 0x40,
0x7F, 0x02, 0x1C, 0x02, 0x7F,
0x7F, 0x04, 0x08, 0x10, 0x7F,
0x3E, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x09, 0x09, 0x09, 0x06,
0x3E, 0x41, 0x51, 0x21, 0x5E,
0x7F, 0x09, 0x19, 0x29, 0x46,
0x26, 0x49, 0x49, 0x49, 0x32,
0x03, 0x01, 0x7F, 0x01, 0x03,
0x3F, 0x40, 0x40, 0x40, 0x3F,
0x1F, 0x20, 0x40, 0x20, 0x1F,
0x3F, 0x40, 0x38, 0x40, 0x3F,
0x63, 0x14, 0x08, 0x14, 0x63,
0x03, 0x04, 0x78, 0x04, 0x03,
0x61, 0x59, 0x49, 0x4D, 0x43,
0x00, 0x7F, 0x41, 0x41, 0x41,
0x02, 0x04, 0x08, 0x10, 0x20,
0x00, 0x41, 0x41, 0x41, 0x7F,
0x04, 0x02, 0x01, 0x02, 0x04,
0x40, 0x40, 0x40, 0x40, 0x40,
0x00, 0x03, 0x07, 0x08, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40,
0x7F, 0x28, 0x44, 0x44, 0x38,
0x38, 0x44, 0x44, 0x44, 0x28,
0x38, 0x44, 0x44, 0x28, 0x7F,
0x38, 0x54, 0x54, 0x54, 0x18,
0x00, 0x08, 0x7E, 0x09, 0x02,
0x18, 0xA4, 0xA4, 0x9C, 0x78,
0x7F, 0x08, 0x04, 0x04, 0x78,
0x00, 0x44, 0x7D, 0x40, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78,
0x7C, 0x08, 0x04, 0x04, 0x78,
0x38, 0x44, 0x44, 0x44, 0x38,
0xFC, 0x18, 0x24, 0x24, 0x18,
0x18, 0x24, 0x24, 0x18, 0xFC,
0x7C, 0x08, 0x04, 0x04, 0x08,
0x48, 0x54, 0x54, 0x54, 0x24,
0x04, 0x04, 0x3F, 0x44, 0x24,
0x3C, 0x40, 0x40, 0x20, 0x7C,
0x1C, 0x20, 0x40, 0x20, 0x1C,
0x3C, 0x40, 0x30, 0x40, 0x3C,
0x44, 0x28, 0x10, 0x28, 0x44,
0x4C, 0x90, 0x90, 0x90, 0x7C,
0x44, 0x64, 0x54, 0x4C, 0x44,
0x00, 0x08, 0x36, 0x41, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02,
0x3C, 0x26, 0x23, 0x26, 0x3C,
0x1E, 0xA1, 0xA1, 0x61, 0x12,
0x3A, 0x40, 0x40, 0x20, 0x7A,
0x38, 0x54, 0x54, 0x55, 0x59,
0x21, 0x55, 0x55, 0x79, 0x41,
0x21, 0x54, 0x54, 0x78, 0x41,
0x21, 0x55, 0x54, 0x78, 0x40,
0x20, 0x54, 0x55, 0x79, 0x40,
0x0C, 0x1E, 0x52, 0x72, 0x12,
0x39, 0x55, 0x55, 0x55, 0x59,
0x39, 0x54, 0x54, 0x54, 0x59,
0x39, 0x55, 0x54, 0x54, 0x58,
0x00, 0x00, 0x45, 0x7C, 0x41,
0x00, 0x02, 0x45, 0x7D, 0x42,
0x00, 0x01, 0x45, 0x7C, 0x40,
0xF0, 0x29, 0x24, 0x29, 0xF0,
0xF0, 0x28, 0x25, 0x28, 0xF0,
0x7C, 0x54, 0x55, 0x45, 0x00,
0x20, 0x54, 0x54, 0x7C, 0x54,
0x7C, 0x0A, 0x09, 0x7F, 0x49,
0x32, 0x49, 0x49, 0x49, 0x32,
0x32, 0x48, 0x48, 0x48, 0x32,
0x32, 0x4A, 0x48, 0x48, 0x30,
0x3A, 0x41, 0x41, 0x21, 0x7A,
0x3A, 0x42, 0x40, 0x20, 0x78,
0x00, 0x9D, 0xA0, 0xA0, 0x7D,
0x39, 0x44, 0x44, 0x44, 0x39,
0x3D, 0x40, 0x40, 0x40, 0x3D,
0x3C, 0x24, 0xFF, 0x24, 0x24,
0x48, 0x7E, 0x49, 0x43, 0x66,
0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
0xFF, 0x09, 0x29, 0xF6, 0x20,
0xC0, 0x88, 0x7E, 0x09, 0x03,
0x20, 0x54, 0x54, 0x79, 0x41,
0x00, 0x00, 0x44, 0x7D, 0x41,
0x30, 0x48, 0x48, 0x4A, 0x32,
0x38, 0x40, 0x40, 0x22, 0x7A,
0x00, 0x7A, 0x0A, 0x0A, 0x72,
0x7D, 0x0D, 0x19, 0x31, 0x7D,
0x26, 0x29, 0x29, 0x2F, 0x28,
0x26, 0x29, 0x29, 0x29, 0x26,
0x30, 0x48, 0x4D, 0x40, 0x20,
0x38, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x38,
0x2F, 0x10, 0xC8, 0xAC, 0xBA,
0x2F, 0x10, 0x28, 0x34, 0xFA,
0x00, 0x00, 0x7B, 0x00, 0x00,
0x08, 0x14, 0x2A, 0x14, 0x22,
0x22, 0x14, 0x2A, 0x14, 0x08,
0xAA, 0x00, 0x55, 0x00, 0xAA,
0xAA, 0x55, 0xAA, 0x55, 0xAA,
0x00, 0x00, 0x00, 0xFF, 0x00,
0x10, 0x10, 0x10, 0xFF, 0x00,
0x14, 0x14, 0x14, 0xFF, 0x00,
0x10, 0x10, 0xFF, 0x00, 0xFF,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x14, 0x14, 0x14, 0xFC, 0x00,
0x14, 0x14, 0xF7, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x14, 0x14, 0xF4, 0x04, 0xFC,
0x14, 0x14, 0x17, 0x10, 0x1F,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0x1F, 0x00,
0x10, 0x10, 0x10, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x10,
0x10, 0x10, 0x10, 0x1F, 0x10,
0x10, 0x10, 0x10, 0xF0, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0xFF, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x14,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x1F, 0x10, 0x17,
0x00, 0x00, 0xFC, 0x04, 0xF4,
0x14, 0x14, 0x17, 0x10, 0x17,
0x14, 0x14, 0xF4, 0x04, 0xF4,
0x00, 0x00, 0xFF, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0xF7, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x17, 0x14,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0xF4, 0x14,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x00, 0x00, 0x1F, 0x10, 0x1F,
0x00, 0x00, 0x00, 0x1F, 0x14,
0x00, 0x00, 0x00, 0xFC, 0x14,
0x00, 0x00, 0xF0, 0x10, 0xF0,
0x10, 0x10, 0xFF, 0x10, 0xFF,
0x14, 0x14, 0x14, 0xFF, 0x14,
0x10, 0x10, 0x10, 0x1F, 0x00,
0x00, 0x00, 0x00, 0xF0, 0x10,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x38, 0x44, 0x44, 0x38, 0x44,
0x7C, 0x2A, 0x2A, 0x3E, 0x14,
0x7E, 0x02, 0x02, 0x06, 0x06,
0x02, 0x7E, 0x02, 0x7E, 0x02,
0x63, 0x55, 0x49, 0x41, 0x63,
0x38, 0x44, 0x44, 0x3C, 0x04,
0x40, 0x7E, 0x20, 0x1E, 0x20,
0x06, 0x02, 0x7E, 0x02, 0x02,
0x99, 0xA5, 0xE7, 0xA5, 0x99,
0x1C, 0x2A, 0x49, 0x2A, 0x1C,
0x4C, 0x72, 0x01, 0x72, 0x4C,
0x30, 0x4A, 0x4D, 0x4D, 0x30,
0x30, 0x48, 0x78, 0x48, 0x30,
0xBC, 0x62, 0x5A, 0x46, 0x3D,
0x3E, 0x49, 0x49, 0x49, 0x00,
0x7E, 0x01, 0x01, 0x01, 0x7E,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x44, 0x44, 0x5F, 0x44, 0x44,
0x40, 0x51, 0x4A, 0x44, 0x40,
0x40, 0x44, 0x4A, 0x51, 0x40,
0x00, 0x00, 0xFF, 0x01, 0x03,
0xE0, 0x80, 0xFF, 0x00, 0x00,
0x08, 0x08, 0x6B, 0x6B, 0x08,
0x36, 0x12, 0x36, 0x24, 0x36,
0x06, 0x0F, 0x09, 0x0F, 0x06,
0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x00, 0x10, 0x10, 0x00,
0x30, 0x40, 0xFF, 0x01, 0x01,
0x00, 0x1F, 0x01, 0x01, 0x1E,
0x00, 0x19, 0x1D, 0x17, 0x12,
0x00, 0x3C, 0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00,
};
#endif
/PIC Stuff/Cerebot_32MX7_LED_Cube/BTN.h
0,0 → 1,31
#ifndef BTN_H
#define BTN_H
 
// BTN1 = CN8, BTN2 = CN9, BTN3 = CN19 (32MX7 only)
// BTN1 = RG6, BTN2 = RG7, BTN3 = RD13 (32MX7 only)
// Note: Write to PORTx is effectively the same as write to LATx
#define BTN1_TRIS TRISGbits.TRISG6
#define BTN1_PORT PORTGbits.RG6
#define BTN2_TRIS TRISGbits.TRISG7
#define BTN2_PORT PORTGbits.RG7
 
#if defined CEREBOT_32MX7
#define BTN3_TRIS TRISDbits.TRISD13
#define BTN3_PORT PORTDbits.RD13
#elif defined CEREBOT_MX7CK
#define BTN3_TRIS TRISAbits.TRISA0
#define BTN3_PORT PORTAbits.RA0
#endif
 
#define BTN_DEBOUNCE_MS 1
 
typedef struct {
void (*callback_function_1)(void);
void (*callback_function_2)(void);
void (*callback_function_3)(void);
} BTN_DATA;
 
void BTN_Init(BTN_DATA *data, void (*callback_1)(void), void (*callback_2)(void), void (*callback_3)(void));
 
#endif /* BTN_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/PWM2.h
0,0 → 1,9
#ifndef PWM2_H
#define PWM2_H
 
void PWM2_Init(void);
void PWM2_Start(void);
void PWM2_Stop(void);
 
#endif /* PWM2_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/Makefile
0,0 → 1,108
#
# There exist several targets which are by default empty and which can be
# used for execution of your targets. These targets are usually executed
# before and after some main targets. They are:
#
# .build-pre: called before 'build' target
# .build-post: called after 'build' target
# .clean-pre: called before 'clean' target
# .clean-post: called after 'clean' target
# .clobber-pre: called before 'clobber' target
# .clobber-post: called after 'clobber' target
# .all-pre: called before 'all' target
# .all-post: called after 'all' target
# .help-pre: called before 'help' target
# .help-post: called after 'help' target
#
# Targets beginning with '.' are not intended to be called on their own.
#
# Main targets can be executed directly, and they are:
#
# build build a specific configuration
# clean remove built files from a configuration
# clobber remove all built files
# all build all configurations
# help print help mesage
#
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
# .help-impl are implemented in nbproject/makefile-impl.mk.
#
# Available make variables:
#
# CND_BASEDIR base directory for relative paths
# CND_DISTDIR default top distribution directory (build artifacts)
# CND_BUILDDIR default top build directory (object files, ...)
# CONF name of current configuration
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
#
# NOCDDL
 
 
# Environment
MKDIR=mkdir
CP=cp
CCADMIN=CCadmin
RANLIB=ranlib
 
 
# build
build: .build-post
 
.build-pre:
# Add your pre 'build' code here...
 
.build-post: .build-impl
# Add your post 'build' code here...
 
 
# clean
clean: .clean-post
 
.clean-pre:
# Add your pre 'clean' code here...
 
.clean-post: .clean-impl
# Add your post 'clean' code here...
 
 
# clobber
clobber: .clobber-post
 
.clobber-pre:
# Add your pre 'clobber' code here...
 
.clobber-post: .clobber-impl
# Add your post 'clobber' code here...
 
 
# all
all: .all-post
 
.all-pre:
# Add your pre 'all' code here...
 
.all-post: .all-impl
# Add your post 'all' code here...
 
 
# help
help: .help-post
 
.help-pre:
# Add your pre 'help' code here...
 
.help-post: .help-impl
# Add your post 'help' code here...
 
 
 
# include project implementation makefile
include nbproject/Makefile-impl.mk
 
# include project make variables
include nbproject/Makefile-variables.mk