0,0 → 1,355 |
// <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 "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 |
static BOARD_STATE op_state __attribute__((persistent)); |
|
uint8_t Get_Board_State(void) { |
return op_state.cube_mode; |
} |
|
void Reset_Board(uint8_t next_state) { |
op_state.cube_mode = 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; |
|
// 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, &Controller_Update, 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, 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 |
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.cube_mode = BOARD_MODE_IDLE; |
} |
|
PWM2_Start(); |
TIMER5_Start(); |
TIMER4_Start(); |
|
/* -------------------- END OF INITIALIZATION -------------------- */ |
/* ------------------------ BEGIN DISPLAY ------------------------ */ |
|
switch (op_state.cube_mode) { |
case BOARD_MODE_SNAKE:; |
Controller_Init(&ctrl_data, &Snake_Update_Direction); |
Snake_Init(&snake_data); |
Snake_Main(); |
break; |
case BOARD_MODE_TRON: |
Controller_Init(&ctrl_data, &Tron_Update_Direction); |
Tron_Init(&tron_data); |
Tron_Main(); |
break; |
case BOARD_MODE_IDLE: |
default: |
Idle_Animation_Sequence(); |
break; |
} |
|
} |
|
void Idle_Animation_Sequence(void) { |
Delay_MS(250); |
|
// 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, &Controller_Update, &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 AMP Lab "; |
Cube_Text_Init(text_string, 27, 0xFF, 0xFF, 0xFF); |
|
// Loop through some preset animations |
while(1) { |
// 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); |
|
// ClearWDT(); // Clear the WDT if we dont want the board to reset |
} |
} |
|
// Function call on button 1 press to change refresh rate |
void BTN1_Interrupt(void) { |
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; |
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(); |
//} |