/PIC Stuff/Cerebot_32MX7_LED_Cube/BTN.c |
---|
3,15 → 3,15 |
#include "defines.h" |
#include "BTN.h" |
static void (*callback_function_1)(void); |
static void (*callback_function_2)(void); |
static void (*callback_function_3)(void); |
static BTN_DATA *btn_data_ptr; |
void BTN_Init(void (*callback_1)(void), void (*callback_2)(void), void (*callback_3)(void)) { |
callback_function_1 = callback_1; |
callback_function_2 = callback_2; |
callback_function_3 = callback_3; |
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; |
31,25 → 31,26 |
} |
void __ISR(_CHANGE_NOTICE_VECTOR, ipl1) __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 (callback_function_1 != NULL) |
(*callback_function_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 (callback_function_2 != NULL) |
(*callback_function_2)(); |
if (btn_data_ptr->callback_function_2 != NULL) |
(*btn_data_ptr->callback_function_2)(); |
} |
} |
if (BTN3_PORT == 1) { |
Delay_MS(BTN_DEBOUNCE_MS); |
if (BTN3_PORT == 1) { |
if (callback_function_3 != NULL) |
(*callback_function_3)(); |
if (btn_data_ptr->callback_function_3 != NULL) |
(*btn_data_ptr->callback_function_3)(); |
} |
} |
IFS1CLR = 0x1; // Clear interrupt flag |
/PIC Stuff/Cerebot_32MX7_LED_Cube/BTN.h |
---|
13,7 → 13,13 |
#define BTN_DEBOUNCE_MS 1 |
void BTN_Init(void (*callback_1)(void), void (*callback_2)(void), void (*callback_3)(void)); |
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/CUBE.c |
---|
5,7 → 5,6 |
#include "SPI1.h" |
static CUBE_DATA *cube_data_ptr; |
static unsigned char current_layer; |
inline void Cube_Delay() { |
// Small delay to ensure that latch speeds are < 30Mhz |
16,7 → 15,7 |
void Cube_Init(CUBE_DATA *data, char BC) { |
cube_data_ptr = data; |
current_layer = 0; |
cube_data_ptr->current_layer = 0; |
SFT_D = 0; |
SFT_S = 0; |
50,7 → 49,7 |
void Cube_Timer_Interrupt(void) { |
// Write to the GCS register |
SPI1_Write(cube_data_ptr->GCS[current_layer], GCS_LAYER_SIZE, &Cube_GCS_Write_Callback); |
SPI1_Write(cube_data_ptr->GCS[cube_data_ptr->current_layer], GCS_LAYER_SIZE, &Cube_GCS_Write_Callback); |
} |
void Cube_DCS_Write_Callback(void) { |
72,7 → 71,7 |
int i; |
for (i = 0; i < CUBE_LAYER_COUNT; i++) { |
Cube_Delay(); |
SFT_D = (i == CUBE_LAYER_COUNT - current_layer - 1) ? 1 : 0; |
SFT_D = (i == CUBE_LAYER_COUNT - cube_data_ptr->current_layer - 1) ? 1 : 0; |
Cube_Delay(); |
SFT_K = 1; |
Cube_Delay(); |
88,10 → 87,12 |
Cube_Delay(); |
GSLAT = 0; |
current_layer = (current_layer == CUBE_LAYER_COUNT-1) ? 0 : current_layer + 1; |
cube_data_ptr->current_layer = (cube_data_ptr->current_layer == CUBE_LAYER_COUNT-1) |
? 0 : cube_data_ptr->current_layer + 1; |
} |
void Cube_Write_DCS(char BC) { |
// Ensure that the brightness isnt set too high |
if (BC > CUBE_MAX_BRIGHTNESS) |
BC = CUBE_MAX_BRIGHTNESS; |
117,7 → 118,7 |
GSLAT = 1; |
SPI1_Write(DCS, GCS_LAYER_SIZE, &Cube_DCS_Write_Callback); |
Delay_MS(8); // Delay until the entire DCS write is finished |
Delay_MS(10); // Delay until the entire DCS write is finished |
} |
void Cube_Clear(void) { |
128,6 → 129,7 |
} |
void Cube_Set_All(int R, int G, int B) { |
// Set all pixels in the cube to the given color |
R &= 0x0FFF; |
G &= 0x0FFF; |
B &= 0x0FFF; |
152,6 → 154,7 |
} |
void Cube_Set_Layer(int layer, int R, int G, int B) { |
// Set all pixels in the specified layer to the given color |
R &= 0x0FFF; |
G &= 0x0FFF; |
B &= 0x0FFF; |
174,6 → 177,7 |
} |
void Cube_Set_Pixel(int layer, int row, int column, int R, int G, int B) { |
// Set the specified pixel to the given color |
R &= 0x0FFF; |
G &= 0x0FFF; |
B &= 0x0FFF; |
/PIC Stuff/Cerebot_32MX7_LED_Cube/CUBE.h |
---|
36,6 → 36,7 |
typedef struct { |
unsigned char GCS[CUBE_LAYER_COUNT][GCS_LAYER_SIZE]; |
unsigned char current_layer; |
} CUBE_DATA; |
void Cube_Init(CUBE_DATA *data, char BC); |
/PIC Stuff/Cerebot_32MX7_LED_Cube/SPI1.c |
---|
3,16 → 3,15 |
#include "defines.h" |
#include "SPI1.h" |
static SPI1_DATA *data_ptr; |
static void (*callback_function)(void); |
static SPI1_DATA *spi_data_ptr; |
void SPI1_Init(SPI1_DATA *data) { |
data_ptr = data; |
data_ptr->outBufferInd = 0; |
data_ptr->outBufferLen = 0; |
spi_data_ptr = data; |
spi_data_ptr->outBufferInd = 0; |
spi_data_ptr->outBufferLen = 0; |
#ifndef SPI1_WRITE_ONLY |
data_ptr->inBufferInd = 0; |
data_ptr->inBufferLen = 0; |
spi_data_ptr->inBufferInd = 0; |
spi_data_ptr->inBufferLen = 0; |
#endif |
INTDisableInterrupts(); |
53,7 → 52,7 |
int SPI1_Read_Buffer(unsigned char *array, unsigned int count) { |
if (count > SPI1_BUFFER_SIZE) |
return 0; |
if (data_ptr->inBufferLen == 0) |
if (spi_data_ptr->inBufferLen == 0) |
return 0; |
// Save previous interrupt state |
60,14 → 59,14 |
int prev = IEC0 & 0x03800000; |
// Temporarily disable interrupts |
IEC0CLR = 0x03800000; |
int ret = data_ptr->inBufferLen; |
int ret = spi_data_ptr->inBufferLen; |
int i; |
for (i = 0; i < count; i++) { |
array[i] = data_ptr->inBuffer[i]; |
array[i] = spi_data_ptr->inBuffer[i]; |
} |
// Reset buffer pointers |
data_ptr->inBufferInd = 0; |
data_ptr->inBufferLen = 0; |
spi_data_ptr->inBufferInd = 0; |
spi_data_ptr->inBufferLen = 0; |
// Restore saved interrupt state |
IEC0SET = prev; |
// Return the number of valid bytes in the buffer |
76,18 → 75,18 |
#endif |
int SPI1_Write(unsigned char *array, unsigned int count, void (*callback)(void)) { |
callback_function = callback; |
spi_data_ptr->callback_function = callback; |
if (count > SPI1_BUFFER_SIZE) |
return 0; |
if (data_ptr->outBufferLen != 0) |
if (spi_data_ptr->outBufferLen != 0) |
return 0; |
data_ptr->outBufferLen = count; |
data_ptr->outBufferInd = count-1; |
spi_data_ptr->outBufferLen = count; |
spi_data_ptr->outBufferInd = count-1; |
int i; |
for (i = 0; i < count; i++) { |
data_ptr->outBuffer[i] = array[i]; |
spi_data_ptr->outBuffer[i] = array[i]; |
} |
IEC0SET = 0x02000000; // Enable TX interrupt |
return 1; |
109,11 → 108,11 |
int i; |
// Read the data received from the last transfer |
int rxBufferCount = SPI1STATbits.RXBUFELM; |
if (data_ptr->inBufferLen + rxBufferCount < SPI1_BUFFER_SIZE) { |
if (spi_data_ptr->inBufferLen + rxBufferCount < SPI1_BUFFER_SIZE) { |
for (i = 0; i < rxBufferCount; i++) { |
data_ptr->inBuffer[data_ptr->inBufferInd] = SPI1BUF; |
data_ptr->inBufferInd++; |
data_ptr->inBufferLen++; |
spi_data_ptr->inBuffer[spi_data_ptr->inBufferInd] = SPI1BUF; |
spi_data_ptr->inBufferInd++; |
spi_data_ptr->inBufferLen++; |
} |
} else { |
// If buffer is full, discard data in enhanced buffer |
129,25 → 128,25 |
if (IFS0bits.SPI1TXIF) { |
int i; |
// Disable the transmit interrupt if all data has been sent |
if (data_ptr->outBufferLen == 0) { |
if (spi_data_ptr->outBufferLen == 0) { |
IEC0CLR=0x02000000; |
if (callback_function != NULL) |
(*callback_function)(); |
if (spi_data_ptr->callback_function != NULL) |
(*spi_data_ptr->callback_function)(); |
} else { |
// Start transmitting the data in the buffer |
int txBufferFree = 16 - SPI1STATbits.TXBUFELM; |
if (data_ptr->outBufferLen > txBufferFree) { |
if (spi_data_ptr->outBufferLen > txBufferFree) { |
for (i = 0; i < txBufferFree; i++) { |
SPI1BUF = data_ptr->outBuffer[data_ptr->outBufferInd]; |
data_ptr->outBufferInd--; |
SPI1BUF = spi_data_ptr->outBuffer[spi_data_ptr->outBufferInd]; |
spi_data_ptr->outBufferInd--; |
} |
data_ptr->outBufferLen -= txBufferFree; |
spi_data_ptr->outBufferLen -= txBufferFree; |
} else { |
for (i = 0; i < data_ptr->outBufferLen; i++) { |
SPI1BUF = data_ptr->outBuffer[data_ptr->outBufferInd]; |
data_ptr->outBufferInd--; |
for (i = 0; i < spi_data_ptr->outBufferLen; i++) { |
SPI1BUF = spi_data_ptr->outBuffer[spi_data_ptr->outBufferInd]; |
spi_data_ptr->outBufferInd--; |
} |
data_ptr->outBufferLen = 0; |
spi_data_ptr->outBufferLen = 0; |
} |
} |
IFS0CLR = 0x02000000; // Clear the TX flag |
/PIC Stuff/Cerebot_32MX7_LED_Cube/SPI1.h |
---|
15,6 → 15,7 |
int inBufferInd; |
int inBufferLen; |
#endif |
void (*callback_function)(void); |
} SPI1_DATA; |
void SPI1_Init(SPI1_DATA *data); |
/PIC Stuff/Cerebot_32MX7_LED_Cube/TIMER5.c |
---|
3,10 → 3,15 |
#include "defines.h" |
#include "TIMER5.h" |
static void (*callback_function)(void); |
static TIMER_DATA *timer_data_ptr; |
void TIMER5_Init(void (*callback)(void), unsigned int time_us) { |
callback_function = callback; |
void TIMER5_Init(TIMER_DATA *data, void (*callback)(void), unsigned int time_us) { |
if (data != NULL) // if ptr is null, use existing data |
timer_data_ptr = data; |
timer_data_ptr->callback_function = callback; |
// Note: PR5 is 16-bit wide! (max time_us = 13107) |
int time = 5 * time_us; |
INTDisableInterrupts(); |
32,7 → 37,7 |
void __ISR(_TIMER_5_VECTOR, ipl4) __TIMER_5_Interrupt_Handler(void) { |
// Call the saved callback function |
(*callback_function)(); |
(*timer_data_ptr->callback_function)(); |
IFS0CLR = 0x00100000; // Clear the timer interrupt flag |
} |
/PIC Stuff/Cerebot_32MX7_LED_Cube/TIMER5.h |
---|
1,7 → 1,11 |
#ifndef TIMER5_H |
#define TIMER5_H |
void TIMER5_Init(void (*callback)(void), unsigned int time_us); |
typedef struct { |
void (*callback_function)(void); |
} TIMER_DATA; |
void TIMER5_Init(TIMER_DATA *data, void (*callback)(void), unsigned int time_us); |
void TIMER5_Start(void); |
void TIMER5_Stop(void); |
/PIC Stuff/Cerebot_32MX7_LED_Cube/main.c |
---|
57,6 → 57,8 |
void Animation_Cube_In_Cube(int iterations, int delay_ms); |
void Delay_MS(unsigned int delay_ms) { |
// Delays the CPU for the given amount of time. |
// Note: Watch out for integer overflow! (max delay_ms = 107374) ?? |
unsigned int delay = delay_ms * MS_TO_CT_TICKS; |
unsigned int startTime = ReadCoreTimer(); |
while ((unsigned int)(ReadCoreTimer() - startTime) < delay) {}; |
63,6 → 65,8 |
} |
void Delay_US(unsigned int delay_us) { |
// Delays the CPU for the given amount of time. |
// Note: Watch out for integer overflow! |
unsigned int delay = delay_us * US_TO_CT_TICKS; |
unsigned int startTime = ReadCoreTimer(); |
while ((unsigned int)(ReadCoreTimer() - startTime) < delay) {}; |
79,6 → 83,7 |
// Set all analog I/O pins to digital |
AD1PCFGSET = 0xFFFF; |
// Initialize peripherals |
SPI1_DATA spi_data; |
SPI1_Init(&spi_data); |
89,11 → 94,14 |
Cube_Init(&cube_data, 0x01); |
// 2083 = 60Hz, 500 = 250Hz, 250 = 500Hz |
TIMER5_Init(&Cube_Timer_Interrupt, 500); |
TIMER_DATA timer_data; |
TIMER5_Init(&timer_data, &Cube_Timer_Interrupt, 500); |
TIMER5_Start(); |
BTN_Init(&BTN1_Interrupt, &BTN2_Interrupt, NULL); |
BTN_DATA btn_data; |
BTN_Init(&btn_data, &BTN1_Interrupt, &BTN2_Interrupt, NULL); |
// Begin display |
Cube_Set_All(0xFF,0xFF,0xFF); |
Delay_MS(3000); |
117,16 → 125,16 |
TIMER5_Stop(); |
switch (state) { |
case 0: |
TIMER5_Init(&Cube_Timer_Interrupt, 500); |
TIMER5_Init(NULL, &Cube_Timer_Interrupt, 500); |
break; |
case 1: |
TIMER5_Init(&Cube_Timer_Interrupt, 2083); |
TIMER5_Init(NULL, &Cube_Timer_Interrupt, 2083); |
break; |
case 2: |
TIMER5_Init(&Cube_Timer_Interrupt, 4166); |
TIMER5_Init(NULL, &Cube_Timer_Interrupt, 4166); |
break; |
case 3: |
TIMER5_Init(&Cube_Timer_Interrupt, 13107); |
TIMER5_Init(NULL, &Cube_Timer_Interrupt, 13107); |
break; |
} |
TIMER5_Start(); |
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-genesis.properties |
---|
1,5 → 1,5 |
# |
#Fri May 24 23:27:07 EDT 2013 |
#Tue May 28 00:19:11 EDT 2013 |
default.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=6b4fa04caf3910c7c3a4666b1aea8c5c |
default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\xc32\\v1.20\\bin |
com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=415494acd195d89b2f6d7a36797a5ab4 |