/PIC Stuff/Cerebot_32MX7_LED_Cube/CUBE.h |
---|
19,6 → 19,7 |
#define TEAL 0x000,0x08F,0x08F |
#define BLUE 0x000,0x000,0x08F |
#define PURPLE 0x08F,0x000,0x08F |
#define WHITE 0x0FF,0x0FF,0x0FF |
// Control Pin Declarations |
#define SFT_D_TRIS TRISBbits.TRISB15 |
/PIC Stuff/Cerebot_32MX7_LED_Cube/README.txt |
---|
2,6 → 2,7 |
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 |
/PIC Stuff/Cerebot_32MX7_LED_Cube/SNAKE.c |
---|
7,13 → 7,8 |
void Snake_Init(SNAKE_DATA *data) { |
data_p = data; |
// Disable watchdog timer |
WDTCON = 0x00000000; |
// Set starting point |
data_p->body[0].x = 0; |
data_p->body[0].y = 0; |
data_p->body[0].z = 0; |
data_p->body[0] = (SNAKE_POINT){0,0,7}; |
data_p->pos_head = 0; |
data_p->pos_tail = 0; |
37,6 → 32,7 |
} |
void Snake_Main(void) { |
// Main function, loops and delays while updating the frame every x milliseconds |
Delay_MS(2000); |
while (1) { |
Snake_Update_Frame(); |
93,6 → 89,7 |
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_Overlay_Set_Pixel(data_p->direction.z, data_p->direction.x, data_p->direction.y, SNAKE_HEAD_COLOR); |
Delay_MS(3000); |
Reset_Board(BOARD_MODE_IDLE); |
123,12 → 120,16 |
// If we ate a candy, delay for a bit to rest |
if (om_nom_nom) { |
data_p->level += 1; // Increase the level by one |
// 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); |
} |
data_p->delay -= 5; // Decrease the delay between frame updates by 5ms |
// 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(); |
} |
} |
/PIC Stuff/Cerebot_32MX7_LED_Cube/TRON.c |
---|
0,0 → 1,160 |
#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 = 0; |
Cube_Set_Pixel(data_p->p1_body[index].z, data_p->p1_body[index].x, data_p->p1_body[index].y, TRON_PLAYER_1_HEAD); |
for (index = 1; index < data_p->length; 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); |
} |
// Draw player 2 light trail |
index = 0; |
Cube_Set_Pixel(data_p->p2_body[index].z, data_p->p2_body[index].x, data_p->p2_body[index].y, TRON_PLAYER_2_HEAD); |
for (index = 1; index < data_p->length; 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); |
} |
} |
void Tron_Main(void) { |
// Main function, loops and delays while updating the frame every x milliseconds |
Delay_MS(2000); |
Tron_Update_Direction(0x04,0x04); |
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); |
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 |
index = 0; |
Cube_Set_Pixel(data_p->p1_body[index].z, data_p->p1_body[index].x, data_p->p1_body[index].y, TRON_PLAYER_1_HEAD); |
for (index = 1; index < data_p->length; 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); |
} |
// Draw player 2 light trail |
index = 0; |
Cube_Set_Pixel(data_p->p2_body[index].z, data_p->p2_body[index].x, data_p->p2_body[index].y, TRON_PLAYER_2_HEAD); |
for (index = 1; index < data_p->length; 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); |
} |
// 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); |
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/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/main.c |
---|
47,6 → 47,7 |
#include "ANIMATIONS.h" |
#include "CONTROLLERS.h" |
#include "SNAKE.h" |
#include "TRON.h" |
void BTN1_Interrupt(void); |
void BTN2_Interrupt(void); |
179,9 → 180,10 |
// Initialize controllers |
CONTROLLER_DATA ctrl_data; |
Controller_Init(&ctrl_data, &Snake_Update_Direction); |
Controller_Init(&ctrl_data, NULL); |
SNAKE_DATA snake_data; |
TRON_DATA tron_data; |
// 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 |
205,12 → 207,15 |
/* ------------------------ BEGIN DISPLAY ------------------------ */ |
switch (op_state.cube_mode) { |
case BOARD_MODE_SNAKE: |
case BOARD_MODE_SNAKE:; |
Controller_Init(&ctrl_data, &Snake_Update_Direction); |
Snake_Init(&snake_data); |
Snake_Main(); |
break; |
case BOARD_MODE_TRON: |
while(1); |
Controller_Init(&ctrl_data, &Tron_Update_Direction); |
Tron_Init(&tron_data); |
Tron_Main(); |
break; |
case BOARD_MODE_IDLE: |
default: |
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-default.mk |
---|
45,17 → 45,17 |
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 |
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 |
# 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 |
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 |
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 |
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 |
# 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 |
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 |
# 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 |
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 |
CFLAGS= |
169,6 → 169,12 |
@${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 |
else |
${OBJECTDIR}/main.o: main.c nbproject/Makefile-${CND_CONF}.mk |
@${MKDIR} ${OBJECTDIR} |
248,6 → 254,12 |
@${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 |
endif |
# ------------------------------------------------------------------------------------ |
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-genesis.properties |
---|
1,5 → 1,5 |
# |
#Thu Dec 12 00:30:32 EST 2013 |
#Thu Dec 12 05:36:33 EST 2013 |
default.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=a7430524a414be59f5ce2a8f8797db6d |
default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\xc32\\v1.21\\bin |
com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=0d2b1469ad71adb787c711a416386331 |
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/configurations.xml |
---|
18,6 → 18,7 |
<itemPath>I2C1.h</itemPath> |
<itemPath>CONTROLLERS.h</itemPath> |
<itemPath>SNAKE.h</itemPath> |
<itemPath>TRON.h</itemPath> |
</logicalFolder> |
<logicalFolder name="LinkerScript" |
displayName="Linker Files" |
39,6 → 40,7 |
<itemPath>I2C1.c</itemPath> |
<itemPath>CONTROLLERS.c</itemPath> |
<itemPath>SNAKE.c</itemPath> |
<itemPath>TRON.c</itemPath> |
</logicalFolder> |
<logicalFolder name="ExternalFiles" |
displayName="Important Files" |
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/private/private.xml |
---|
1,10 → 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"/> |
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/1"> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/main.c</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/SNAKE.c</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/defines.h</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/README.txt</file> |
<file>file:/C:/Users/Kevin/Documents/Code/Cerebot_32MX7_LED_Cube/SNAKE.h</file> |
</open-files> |
</project-private> |