20,7 → 20,7 |
#pragma config FVBUSONIO = OFF // USB VBUS ON Selection |
#pragma config FUSBIDIO = OFF // USB USID Selection |
/* Other Peripheral Device Settings */ |
#pragma config FWDTEN = ON // Watchdog Timer Enable |
#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) |
45,6 → 45,8 |
#include "CUBE.h" |
#include "BTN.h" |
#include "ANIMATIONS.h" |
#include "CONTROLLERS.h" |
#include "SNAKE.h" |
|
void BTN1_Interrupt(void); |
void BTN2_Interrupt(void); |
66,10 → 68,47 |
while ((uint32_t)(ReadCoreTimer() - startTime) < delay) {}; |
} |
|
int32_t main() { |
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; |
} |
|
void Reset_Board(void) { |
// 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. */ |
// Configure the target for maximum performance at 80 MHz. |
// Note: This overrides the peripheral clock to 80Mhz regardless of config |
SYSTEMConfigPerformance(CPU_CLOCK_HZ); |
|
79,6 → 118,11 |
// 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; |
88,6 → 132,9 |
LED3_LAT = 0; |
LED4_LAT = 0; |
|
// Initialize a persistent operational state machine |
BOARD_STATE op_state __attribute__((persistent)); |
|
// Initialize the SPI1 module |
SPI1_DATA spi_1_data; |
SPI1_Init(&spi_1_data, NULL); |
96,6 → 143,7 |
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); |
|
105,7 → 153,6 |
|
// Initializs the PWM2 output to 20MHz |
PWM2_Init(); |
PWM2_Start(); |
|
// Initialize the cube variables |
CUBE_DATA cube_data; |
115,18 → 162,62 |
// 2083 = 60Hz, 500 = 250Hz, 250 = 500Hz |
TIMER5_DATA timer_5_data; |
TIMER5_Init(&timer_5_data, &Cube_Timer_Interrupt, 500); |
TIMER5_Start(); |
|
// Start the overlay rotation interrupt |
// Start the controller polling and overlay rotation interrupt |
TIMER4_DATA timer_4_data; |
TIMER4_Init(&timer_4_data, &Cube_Text_Interrupt, 90000); |
TIMER4_Init(&timer_4_data, &Controller_Update, NULL, 0); |
|
// Process button inputs |
BTN_DATA btn_data; |
BTN_Init(&btn_data, &BTN1_Interrupt, &BTN2_Interrupt, &BTN3_Interrupt); |
BTN_Init(&btn_data, &BTN1_Interrupt, &BTN2_Interrupt, NULL); |
|
// Begin display |
CONTROLLER_DATA ctrl_data; |
Controller_Init(&ctrl_data, &op_state, &Controller_Set_Leds); |
|
// 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(); |
switch (last_reset) { |
// If our last reset was a POR/BOR/PIN/WDT/CFG, go into idle mode |
case RESET_POR: |
case RESET_BOR: |
case RESET_PIN: |
case RESET_WDT: |
case RESET_CFG: |
op_state.cube_mode = BOARD_MODE_IDLE; |
break; |
} |
|
PWM2_Start(); |
TIMER5_Start(); |
TIMER4_Start(); |
|
/* -------------------- END OF INITIALIZATION -------------------- */ |
/* ------------------------ BEGIN DISPLAY ------------------------ */ |
|
switch (op_state.cube_mode) { |
case BOARD_MODE_SNAKE: |
LED3_LAT = 1; |
LED4_LAT = 0; |
SNAKE_DATA snake_data; |
Snake_Init(&snake_data); |
while(1); |
break; |
case BOARD_MODE_TRON: |
LED3_LAT = 0; |
LED4_LAT = 1; |
while(1); |
break; |
case BOARD_MODE_IDLE: |
default: |
Idle_Animation_Sequence(); |
break; |
} |
|
} |
|
void Idle_Animation_Sequence(void) { |
|
// Cube_Set_All(RED); |
// Delay_MS(2000); |
// Cube_Set_All(GREEN); |
133,8 → 224,18 |
// Delay_MS(2000); |
// Cube_Set_All(BLUE); |
// Delay_MS(2000); |
// Animation_Pseudo_Random_Colors(10,300); |
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, &Controller_Update, &Cube_Text_Interrupt, 100); |
TIMER4_Start(); |
|
// int8_t start_text[] = "Cube Initialized\r\n"; |
// UART1_Write(start_text, 18); |
|
141,63 → 242,25 |
// Set the overlay text |
uint8_t text_string[] = "Welcome to the AMP Lab "; |
Cube_Text_Init(text_string, 27, 0xFF, 0xFF, 0xFF); |
TIMER4_Start(); |
|
// Loop through some preset animations |
uint8_t buffer1[2]; |
uint8_t buffer2[2]; |
uint8_t result, length; |
|
while(1) { |
I2C1_Master_Restart(0x24, 0xA, 1); |
do { |
result = I2C1_Get_Status(); |
} while (!result); |
if (result == I2C1_RECV_OK) { |
LED1_LAT = 1; |
length = I2C1_Read_Buffer(buffer1); |
buffer1[1] = ~buffer1[0]; |
buffer1[0] = 0xB; |
} else { |
LED1_LAT = 0; |
} |
|
// 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_Row_Column_Sweep(40); |
Animation_Cube_In_Cube(300); |
Animation_Cube_In_Cube(300); |
Animation_Cube_In_Cube(300); |
Animation_Double_Rotation(40); |
Animation_Double_Rotation(40); |
Animation_Double_Rotation(40); |
// Animation_Pseudo_Random_Colors(300); |
// Animation_Random_Colors(300); |
|
I2C1_Master_Restart(0x25, 0xA, 1); |
do { |
result = I2C1_Get_Status(); |
} while (!result); |
if (result == I2C1_RECV_OK) { |
LED2_LAT = 1; |
length = I2C1_Read_Buffer(buffer2); |
buffer2[1] = ~buffer2[0]; |
buffer2[0] = 0xB; |
} else { |
LED2_LAT = 0; |
} |
|
I2C1_Master_Send(0x24, buffer1, 2); |
do { |
result = I2C1_Get_Status(); |
} while (!result); |
|
I2C1_Master_Send(0x25, buffer2, 2); |
do { |
result = I2C1_Get_Status(); |
} while (!result); |
|
Delay_MS(1); |
|
// Animation_Solid_Colors(2,300); |
// Animation_Layer_Alternate(2,300); |
// Animation_Pixel_Alternate(1,200); |
// Animation_Full_Color_Sweep(2,1000); |
// Animation_Row_Column_Sweep(2,40); |
// Animation_Cube_In_Cube(4,300); |
// Animation_Double_Rotation(2,40); |
// Animation_Pseudo_Random_Colors(10,300); |
// Animation_Random_Colors(10,300); |
|
// ClearWDT(); // Clear the WDT if we dont want the board to reset |
} |
} |
261,27 → 324,27 |
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(); |
} |
//// 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(); |
//} |