Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 275 → Rev 276

/PIC Stuff/Cerebot_32MX7_LED_Cube/ANIMATIONS.c
399,7 → 399,7
r = rand();
if (r % 3 == 0) {
// Increase
data[j] = (data[j] == CUBE_LAYER_COUNT - 1) ? data[j] : data[j] + 1;
data[j] = (data[j] == CUBE_LAYER_COUNT) ? data[j] : data[j] + 1;
} else if (r % 3 == 1) {
// Decrease
data[j] = (data[j] == 0) ? data[j] : data[j] - 1;
423,7 → 423,7
r = rand();
if (r % 3 == 0) {
// Increase
data[j] = (data[j] == CUBE_LAYER_COUNT - 1) ? data[j] : data[j] + 1;
data[j] = (data[j] == CUBE_LAYER_COUNT) ? data[j] : data[j] + 1;
} else if (r % 3 == 1) {
// Decrease
data[j] = (data[j] == 0) ? data[j] : data[j] - 1;
/PIC Stuff/Cerebot_32MX7_LED_Cube/CONTROLLERS.c
4,17 → 4,23
 
static CONTROLLER_DATA *ctrl_data_p;
 
void Controller_Init(CONTROLLER_DATA *data) {
ctrl_data_p = data;
void Controller_Init(CONTROLLER_DATA *data,
void (*change_callback)(uint8_t controller, CTRL_BTN_STATUS values)) {
 
if (data != NULL)
ctrl_data_p = data;
ctrl_data_p->change_callback = change_callback;
 
// Variable initialization
int i;
int i, j;
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->led_status[i].w[i] = 0x0;
ctrl_data_p->btn_prev[i].w = 0x0;
ctrl_data_p->btn_curr[i].w = 0x0;
for (j = 0; j < 16; j++) {
ctrl_data_p->led_status[i].w[j] = 0x0;
}
}
 
ctrl_data_p->connected_count = 0x0;
24,157 → 30,167
}
 
void Controller_Poll_Connected(void) {
uint8_t buffer[2] = {CONTROLLER_CMD_RESET};
uint8_t result, length, i;
uint8_t buffer[2];
uint8_t result, 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);
uint8_t 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_controllers[ctrl_data_p->connected_count] = address + i;
ctrl_data_p->connected_count++;
}
 
// A small delay is needed between polls
Delay_MS(1);
}
 
// Show the number of controllers connected
if (ctrl_data_p->connected_count & 0x1)
LED1_LAT = 1;
if (ctrl_data_p->connected_count & 0x2)
LED2_LAT = 1;
if (ctrl_data_p->connected_count & 0x4)
LED3_LAT = 1;
if (ctrl_data_p->connected_count & 0x8)
LED4_LAT = 1;
}
 
void Controller_Update(void) {
/*
uint8_t buffer[2];
uint8_t result, length;
uint8_t ctrl_1_btn = 0, ctrl_2_btn = 0;
uint8_t result, length, i, j;
CTRL_BTN_STATUS btn_change;
for (i = 0; i < ctrl_data_p->connected_count; i++) {
// Store the last read values
ctrl_data_p->btn_prev[i] = ctrl_data_p->btn_curr[i];
 
// 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;
// Read in the button values for each controller
I2C1_Master_Restart(ctrl_data_p->connected_controllers[i], CONTROLLER_CMD_READ, 1);
do {
result = I2C1_Get_Status();
} while (!result);
// Save the read values
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;
ctrl_data_p->btn_curr[i].w = buffer[0];
 
// Determine if a change was made between the current and previous values
if (ctrl_data_p->btn_curr[i].w != ctrl_data_p->btn_prev[i].w) {
// Determine if a button was pressed (unpressed->pressed)
btn_change.w = ctrl_data_p->btn_prev[i].w ^ ctrl_data_p->btn_curr[i].w;
btn_change.w &= ctrl_data_p->btn_curr[i].w;
 
// If a button was pressed, call the saved callback
if (btn_change.w) {
if (ctrl_data_p->change_callback != NULL) {
ctrl_data_p->change_callback(i, btn_change);
}
}
// 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);
void Controller_Set_Left_Leds(uint8_t controller, uint8_t value) {
uint8_t result, i;
uint8_t buffer[18];
 
for (i = 0; i < 4; i++) {
if (value & (0x01 << i))
ctrl_data_p->led_status[controller].w[i+12] = CONTROLLER_BRIGHTNESS_HIGH;
else
ctrl_data_p->led_status[controller].w[i+12] = 0x00;
}
 
// Write the LED value to the controller
buffer[0] = CONTROLLER_CMD_WRITE;
for (i = 0; i < 16; i++)
buffer[i+1] = ctrl_data_p->led_status[controller].w[i];
I2C1_Master_Send(ctrl_data_p->connected_controllers[controller], buffer, 17);
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);
}
Delay_MS(1);
}
 
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);
void Controller_Set_Middle_Leds(uint8_t controller, uint8_t value) {
uint8_t result, i;
uint8_t buffer[18];
 
for (i = 0; i < 8; i++) {
if (value & (0x01 << i))
ctrl_data_p->led_status[controller].w[i] = CONTROLLER_BRIGHTNESS_HIGH;
else
ctrl_data_p->led_status[controller].w[i] = 0x00;
}
 
// 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);
}
// Write the LED value to the controller
buffer[0] = CONTROLLER_CMD_WRITE;
for (i = 0; i < 16; i++)
buffer[i+1] = ctrl_data_p->led_status[controller].w[i];
I2C1_Master_Send(ctrl_data_p->connected_controllers[controller], buffer, 17);
do {
result = I2C1_Get_Status();
} while (!result);
 
Delay_MS(1);
}
 
void Controller_Set_Right_Leds(uint8_t controller, uint8_t value) {
uint8_t result, i;
uint8_t buffer[18];
 
for (i = 0; i < 4; i++) {
if (value & (0x01 << i))
ctrl_data_p->led_status[controller].w[i+8] = CONTROLLER_BRIGHTNESS_HIGH;
else
ctrl_data_p->led_status[controller].w[i+8] = 0x00;
}
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);
}
}
*/
// Write the LED value to the controller
buffer[0] = CONTROLLER_CMD_WRITE;
for (i = 0; i < 16; i++)
buffer[i+1] = ctrl_data_p->led_status[controller].w[i];
I2C1_Master_Send(ctrl_data_p->connected_controllers[controller], buffer, 17);
do {
result = I2C1_Get_Status();
} while (!result);
 
Delay_MS(1);
}
 
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_Get_Connected(void) {
return ctrl_data_p->connected_count;
}
 
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;
void Controller_Set_Active(uint8_t controller) {
uint8_t buffer[2];
uint8_t result;
 
buffer[0] = CONTROLLER_CMD_ACTIVE;
I2C1_Master_Send(ctrl_data_p->connected_controllers[controller], buffer, 1);
do {
result = I2C1_Get_Status();
} while (!result);
 
Delay_MS(1);
}
 
void Controller_Set_Idle(uint8_t controller) {
uint8_t buffer[2];
uint8_t result;
 
buffer[0] = CONTROLLER_CMD_RESET;
I2C1_Master_Send(ctrl_data_p->connected_controllers[controller], buffer, 1);
do {
result = I2C1_Get_Status();
} while (!result);
 
Delay_MS(1);
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/CONTROLLERS.h
4,30 → 4,74
#define CONTROLLER_CMD_READ 0xA
#define CONTROLLER_CMD_WRITE 0xB
#define CONTROLLER_CMD_RESET 0xC
#define CONTROLLER_CMD_ACTIVE 0xD
 
#define CONTROLLER_BTN_DEFAULT 0xC0
#define CONTROLLER_LED_DEFAULT 0x00
 
#define CONTROLLER_PREFIX_ADDRESS 0xA0
#define CONTROLLER_PREFIX_ADDRESS 0x10
#define CONTROLLER_START_ADDRESS 0x01
#define CONTROLLER_END_ADDRESS 0x08
 
#define CONTROLLER_MAX_COUNT 8
#define CONTROLLER_MAX_COUNT 4
 
#define CONTROLLER_BRIGHTNESS_HIGH 0x80
 
typedef union {
struct {
unsigned BTN_L_N :1;
unsigned BTN_L_E :1;
unsigned BTN_R_E :1;
unsigned BTN_R_N :1;
unsigned BTN_R_S :1;
unsigned BTN_R_W :1;
unsigned BTN_L_S :1;
unsigned BTN_L_W :1;
};
uint8_t w;
} CTRL_BTN_STATUS;
 
typedef union {
struct {
uint8_t LED_0;
uint8_t LED_1;
uint8_t LED_2;
uint8_t LED_3;
uint8_t LED_4;
uint8_t LED_5;
uint8_t LED_6;
uint8_t LED_7;
uint8_t LED_N;
uint8_t LED_W;
uint8_t LED_E;
uint8_t LED_S;
uint8_t LED_A;
uint8_t LED_B;
uint8_t LED_C;
uint8_t LED_D;
} single;
uint8_t w[16];
} CTRL_LED_VALUES;
 
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];
void (*change_callback)(uint8_t controller, CTRL_BTN_STATUS values);
 
uint8_t connected_count;
uint8_t connected_controllers[CONTROLLER_MAX_COUNT];
CTRL_LED_VALUES led_status[CONTROLLER_MAX_COUNT];
CTRL_BTN_STATUS btn_prev[CONTROLLER_MAX_COUNT];
CTRL_BTN_STATUS btn_curr[CONTROLLER_MAX_COUNT];
} CONTROLLER_DATA;
 
void Controller_Init(CONTROLLER_DATA *data);
void Controller_Init(CONTROLLER_DATA *data,
void (*change_callback)(uint8_t controller, CTRL_BTN_STATUS values));
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);
void Controller_Set_Left_Leds(uint8_t controller, uint8_t value);
void Controller_Set_Middle_Leds(uint8_t controller, uint8_t value);
void Controller_Set_Right_Leds(uint8_t controller, uint8_t value);
 
uint8_t Controller_Get_Connected(void);
void Controller_Set_Active(uint8_t controller);
void Controller_Set_Idle(uint8_t controller);
 
#endif /* CONTROLLERS_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/CUBE.h
14,8 → 14,8
// Color Definitions
#define CLEAR 0x000,0x000,0x000
#define RED 0x0FF,0x000,0x000
#define ORANGE 0x0FF,0x040,0x000
#define YELLOW 0x0FF,0x0FF,0x000
#define ORANGE 0x0FF,0x020,0x000
#define YELLOW 0x0FF,0x060,0x000
#define GREEN 0x000,0x0FF,0x000
#define TEAL 0x000,0x0FF,0x040
#define BLUE 0x000,0x000,0x0FF
/PIC Stuff/Cerebot_32MX7_LED_Cube/I2C1.c
29,11 → 29,22
// 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)
if (speed == 0x01) {
I2C1BRG = 0x0BE; // Operate at 200kHZ (80MHz)
I2C1CONbits.DISSLW = 0; // Slew rate control enabled
} else if (speed == 0x02) {
I2C1BRG = 0x05A; // Operate at 400kHZ (80MHz)
I2C1CONbits.DISSLW = 1; // Slew rate control disabled
} else if (speed == 0x03) {
I2C1BRG = 0x020; // Operate at 1MHz (80MHz)
I2C1CONbits.DISSLW = 1; // Slew rate control disabled
} else {
I2C1BRG = 0x186; // Operate at 100kHZ (80MHz)
I2C1CONbits.DISSLW = 0; // Slew rate control enabled
}
IFS0CLR = 0xE0000000; // Clear any existing events
IPC6CLR = 0x00001F00; // Reset priority levels
IPC6SET = 0x00001500; // Set IPL=5, Subpriority 1
IPC6SET = 0x00001600; // Set IPL=6, Subpriority 2
IEC0SET = 0xE0000000; // Enable I2C1 interrupts
 
INTEnableInterrupts();
249,7 → 260,8
// 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];
uint8_t to_send = i2c_data_p->buffer_in[0];
I2C1TRN = to_send;
i2c_data_p->operating_state = I2C1_CHECK_ACK_RESTART;
} else {
// If a NACK is received, stop transmission and send error
/PIC Stuff/Cerebot_32MX7_LED_Cube/I2C1.h
4,8 → 4,10
#define MAXI2C1BUF 32
 
// I2C Operating Speed
#define I2C1_400KHZ 0x0
#define I2C1_100KHZ 0x1
#define I2C1_100KHZ 0x0
#define I2C1_200KHZ 0x1
#define I2C1_400KHZ 0x2
#define I2C1_1MHZ 0x3
 
// Operating State
#define I2C1_IDLE 0x1
/PIC Stuff/Cerebot_32MX7_LED_Cube/README.txt
5,14 → 5,14
 
KNOWN ISSUES:
Cube is occasionally flickering to ~60Hz. Need to figure out why.
Interrupts dont seem to be preempting properly. Not sure why.
>= 400MHz I2C1 doesn't seem to work very well the controllers
 
PERIPHERAL USAGE:
SPI1 - Used by the cube code to send data to the ube
SPI1 - Used by the cube code to send data to the cube
SPI4 - Unused
I2C1 - Used by the controller code
TIMER2 - Used by PWM2
TIMER4 - Used by the cube code for the overlay rotation interrupt
TIMER4 - Used by the cube code for the overlay rotation interrupt / controllers
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
20,10 → 20,10
 
PERIPHERAL INTERRUPT PRIORITY LEVELS:
IPL1 = lowest, IPL7 = highest priority
SPI1 - Priority 5, Subpriority 1
SPI1 - Priority 6, Subpriority 1
SPI4 - Priority 6, Subpriority 2
I2C1 - Priority 5, Subpriority 1
TIMER5 - Priority 3, Subpriority 1
I2C1 - Priority 5, Subpriority 2
TIMER5 - Priority 4, Subpriority 1
TIMER4 - Priority 1, Subpriority 1
UART1 - Priority 2, Subpriority 1
ETHERNET - Priority 1, Subpriority 1
/PIC Stuff/Cerebot_32MX7_LED_Cube/SNAKE.c
1,6 → 1,7
#include "defines.h"
#include "CONTROLLERS.h"
#include "SNAKE.h"
#include "TIMER4.h"
 
static SNAKE_DATA *data_p;
static uint32_t rand_value __attribute__((persistent));
14,8 → 15,10
data_p->pos_head = 0;
data_p->pos_tail = 0;
data_p->length = 1;
data_p->level = 1;
data_p->delay = 800;
data_p->level = 0;
data_p->delay = SNAKE_MAXIMUM_DELAY;
data_p->direction = (SNAKE_POINT){1,0,7};
data_p->last_direction = 0x08;
 
srand(rand_value);
 
36,40 → 39,49
 
void Snake_Main(void) {
// Main function, loops and delays while updating the frame every x milliseconds
Delay_MS(2000);
 
while(!Controller_Get_Connected()) {
Delay_MS(100);
Controller_Poll_Connected();
}
 
Controller_Set_Active(0);
Delay_MS(20);
Controller_Set_Left_Leds(0, 0x1);
TIMER4_Start();
Delay_MS(1000);
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) {
void Snake_Update_Direction(uint8_t controller, CTRL_BTN_STATUS value) {
// 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;
if (controller == 0) {
data_p->last_direction = value.w;
SNAKE_POINT point = data_p->body[data_p->pos_head];
 
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;
if (value.BTN_L_N || value.BTN_L_E) { // Up
point.z = (point.z == CUBE_LAYER_COUNT - 1) ? 0 : point.z + 1;
} else if (value.BTN_L_W || value.BTN_L_S) { // Down
point.z = (point.z == 0) ? CUBE_LAYER_COUNT - 1 : point.z - 1;
} else if (value.BTN_R_N) { // Forward
point.x = (point.x == CUBE_ROW_COUNT - 1) ? 0 : point.x + 1;
} else if (value.BTN_R_W) { // Right
point.y = (point.y == CUBE_COLUMN_COUNT - 1) ? 0 : point.y + 1;
} else if (value.BTN_R_S) { // Backward
point.x = (point.x == 0) ? CUBE_ROW_COUNT - 1 : point.x - 1;
} else if (value.BTN_R_E) { // Left
point.y = (point.y== 0) ? CUBE_COLUMN_COUNT - 1 : point.y - 1;
}
 
data_p->direction = point;
}
 
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);
124,18 → 136,22
}
 
// Determine the next direction to take
Snake_Update_Direction(data_p->last_direction, 0x0);
Snake_Update_Direction(0, (CTRL_BTN_STATUS)data_p->last_direction);
 
// 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
// Increase the level by one
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);
}
 
TIMER4_Stop();
Controller_Set_Middle_Leds(0, data_p->level);
if (data_p->level >= 256)
Controller_Set_Left_Leds(0, 0x9);
TIMER4_Start();
 
// Decrease the delay between frame updates by 5ms
data_p->delay -= 5;
if (data_p->delay > SNAKE_MINIMUM_DELAY)
data_p->delay -= 5;
// Clear the watchdog timer to prevent resets in a middle of a game
ClearWDT();
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/SNAKE.h
8,28 → 8,15
#define SNAKE_CANDY_COLOR GREEN
#define SNAKE_COLLISION_COLOR ORANGE
 
#define SNAKE_LEVEL_STEP 10
#define SNAKE_MAXIMUM_DELAY 800
#define SNAKE_MINIMUM_DELAY 300
 
typedef struct {
unsigned x :8;
unsigned y :8;
unsigned z :8;
unsigned :8;
uint8_t x;
uint8_t y;
uint8_t z;
} 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;
44,7 → 31,7
 
void Snake_Init(SNAKE_DATA *data);
void Snake_Main(void);
void Snake_Update_Direction(uint8_t p1, uint8_t p2);
void Snake_Update_Direction(uint8_t controller, CTRL_BTN_STATUS value);
void Snake_Update_Frame(void);
SNAKE_POINT Snake_Generate_Candy(void);
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/TIMER5.c
32,7 → 32,8
Nop();
TMR5 = 0x0; // Clear timer register
PR5 = time; // Load period register
IPC5SET = 0x0000000D; // Set priority level = 3, sub-priority level = 1
// IPC5SET = 0x0000000D; // Set priority level = 3, sub-priority level = 1
IPC5SET = 0x00000011; // Set priority level = 4, sub-priority level = 1
IFS0CLR = 0x00100000; // Clear timer interrupt flag
IEC0SET = 0x00100000; // Enable timer interrupt
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/TRON.c
34,7 → 34,7
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);
// Controller_Set_Leds(0x01,0x01);
Delay_MS(2000);
while (1) {
Tron_Update_Frame();
/PIC Stuff/Cerebot_32MX7_LED_Cube/defines.h
8,8 → 8,8
#include <stdint.h>
 
// Uncomment ONE of the following:
#define CEREBOT_32MX7
// #define CEREBOT_MX7CK
//#define CEREBOT_32MX7
#define CEREBOT_MX7CK
 
#define CPU_CLOCK_HZ 80000000UL
#define PERIPHERAL_CLOCK_HZ 80000000UL
/PIC Stuff/Cerebot_32MX7_LED_Cube/main.c
114,6 → 114,21
while(1);
}
 
void Test_Callback(uint8_t controller, CTRL_BTN_STATUS value) {
LED1_LAT = 0;
LED2_LAT = 0;
LED3_LAT = 0;
LED4_LAT = 0;
if (value.BTN_R_N)
LED1_LAT = 1;
if (value.BTN_R_E)
LED2_LAT = 1;
if (value.BTN_R_S)
LED3_LAT = 1;
if (value.BTN_R_W)
LED4_LAT = 1;
}
 
void main() {
// WARNING!! THIS BOARD WILL RESET EVERY 1048.576s DUE TO THE WDT!!
 
131,7 → 146,8
 
// Enable the watchdog timer with windowed mode disabled
// WDT prescaler set to 1048576 (1048.576s) (see config bits)
WDTCON = 0x00008000;
// WDTCON = 0x00008000;
WDTCON = 0x00000000;
 
// Configure onboard LEDs
LED1_TRIS = 0;
157,12 → 173,12
SPI1_Init(&spi_1_data, NULL);
 
// Initialize the SPI4 module
SPI4_DATA spi_4_data;
SPI4_Init(&spi_4_data);
// 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);
I2C1_Init(&i2c_1_data, I2C1_200KHZ, 0x20);
 
// // Initialize the UART1 module
// UART1_DATA uart_data;
176,11 → 192,11
Cube_Init(&cube_data, 0x40);
 
// Start the cube update layer interrupt
// 2083 = 60Hz, 500 = 250Hz, 250 = 500Hz
// 2084 = 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
// Initialize timer for controller polling and overlay rotation interrupt
TIMER4_DATA timer_4_data;
TIMER4_Init(&timer_4_data, NULL, NULL, 0);
 
190,7 → 206,7
 
// Initialize controllers
CONTROLLER_DATA ctrl_data;
Controller_Init(&ctrl_data);
Controller_Init(&ctrl_data, NULL);
 
// Initialize the Ethernet module
if (op_state == BOARD_MODE_ETHERNET) {
203,7 → 219,6
TRON_DATA tron_data;
 
PWM2_Start();
TIMER5_Start();
/* -------------------- END OF INITIALIZATION -------------------- */
/* ------------------------ BEGIN DISPLAY ------------------------ */
211,24 → 226,35
// Figure out what to do at this point (depending on current state)
switch (op_state) {
case BOARD_MODE_IDLE:
TIMER5_Start(); // Use the default refresh rate (250Hz)
Idle_Animation_Sequence();
break;
case BOARD_MODE_SNAKE:;
Controller_Init(&ctrl_data);
case BOARD_MODE_SNAKE:
// Change refresh rate to ~60Hz
TIMER5_Init(NULL, &Cube_Timer_Interrupt, 2000);
TIMER5_Start();
// Poll the controllers at 1kHz
Controller_Init(NULL, &Snake_Update_Direction);
TIMER4_Init(NULL, &Controller_Update, NULL, 0);
TIMER4_Start();
// Initialize and start the game
Snake_Init(&snake_data);
Snake_Main();
break;
case BOARD_MODE_TRON:
Controller_Init(&ctrl_data);
// Change refresh rate to ~60Hz
TIMER5_Init(NULL, &Cube_Timer_Interrupt, 2000);
TIMER5_Start();
// Poll the controllers at 1kHz
Controller_Init(&ctrl_data, NULL);
TIMER4_Init(NULL, &Controller_Update, NULL, 0);
// Initialize and start the game
Tron_Init(&tron_data);
TIMER4_Start();
Tron_Init(&tron_data);
Tron_Main();
break;
case BOARD_MODE_ETHERNET:
TIMER4_Stop();
TIMER5_Start();
LED2_LAT = 1;
while(1);
break;
250,6 → 276,12
// Animation_Pseudo_Random_Colors(200);
// Animation_Pseudo_Random_Colors(200);
// Animation_Pseudo_Random_Colors(200);
uint8_t connected, i;
connected = Controller_Get_Connected();
for (i = 0; i < connected; i++) {
Controller_Set_Idle(i);
}
 
// Start the scrolling text
TIMER4_Stop();
286,8 → 318,8
// Animation_Layer_Alternate(300);
// Animation_Pixel_Alternate(200);
// Animation_Full_Color_Sweep(1000);
// Animation_Row_Column_Sweep(40);
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);
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-genesis.properties
1,5 → 1,5
#
#Thu Mar 13 23:02:03 EDT 2014
#Mon Mar 17 03:54:28 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
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/configurations.xml
130,13 → 130,6
<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"/>