Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 211 → Rev 212

/PIC Stuff/Cerebot_32MX7_LED_Cube/SPI1.c
5,14 → 5,11
 
static SPI1_DATA *spi_data_ptr;
 
void SPI1_Init(SPI1_DATA *data) {
void SPI1_Init(SPI1_DATA *data, void (*rx_callback)(char)) {
spi_data_ptr = data;
spi_data_ptr->outBufferInd = 0;
spi_data_ptr->outBufferLen = 0;
#ifndef SPI1_WRITE_ONLY
spi_data_ptr->inBufferInd = 0;
spi_data_ptr->inBufferLen = 0;
#endif
spi_data_ptr->buffer_out_ind = 0;
spi_data_ptr->buffer_out_len = 0;
spi_data_ptr->rx_callback = rx_callback;
INTDisableInterrupts();
 
38,7 → 35,7
IPC5SET = 0x19000000; // Set IPL=6, Subpriority 1
SPI1BRG = 0x1; // Use FPB/4 clock frequency
SPI1STATCLR = 0x40; // Clear the Overflow
#ifndef SPI1_WRITE_ONLY
#ifndef SPI_WRITE_ONLY
IEC0SET = 0x01800000; // Enable RX and Error interrupts
#endif
// Enhanced buffer, SPI on, 8 bits transfer, SMP=1, Master mode
48,45 → 45,20
INTEnableInterrupts();
}
 
#ifndef SPI1_WRITE_ONLY
int SPI1_Read_Buffer(unsigned char *array, unsigned int count) {
if (count > SPI1_BUFFER_SIZE)
return 0;
if (spi_data_ptr->inBufferLen == 0)
return 0;
int SPI1_Write(unsigned char *array, unsigned int count, void (*tx_callback)(void)) {
spi_data_ptr->tx_callback = tx_callback;
 
// Save previous interrupt state
int prev = IEC0 & 0x03800000;
// Temporarily disable interrupts
IEC0CLR = 0x03800000;
int ret = spi_data_ptr->inBufferLen;
int i;
for (i = 0; i < count; i++) {
array[i] = spi_data_ptr->inBuffer[i];
}
// Reset buffer pointers
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
return ret;
}
#endif
 
int SPI1_Write(unsigned char *array, unsigned int count, void (*callback)(void)) {
spi_data_ptr->callback_function = callback;
 
if (count > SPI1_BUFFER_SIZE)
return 0;
if (spi_data_ptr->outBufferLen != 0)
if (spi_data_ptr->buffer_out_len != 0)
return 0;
 
spi_data_ptr->outBufferLen = count;
spi_data_ptr->outBufferInd = count-1;
// Put the data to send into the outbound buffer
spi_data_ptr->buffer_out_len = count;
spi_data_ptr->buffer_out_ind = count-1;
int i;
for (i = 0; i < count; i++) {
spi_data_ptr->outBuffer[i] = array[i];
spi_data_ptr->buffer_out[i] = array[i];
}
IEC0SET = 0x02000000; // Enable TX interrupt
return 1;
93,7 → 65,7
}
 
void __ISR(_SPI_1_VECTOR, ipl6) __SPI_1_Interrupt_Handler(void) {
#ifndef SPI1_WRITE_ONLY
#ifndef SPI_WRITE_ONLY
// Process SPI1 error flag
if (IFS0bits.SPI1EIF) {
// Clear the receive overflow bit if it is set
108,17 → 80,11
int i;
// Read the data received from the last transfer
int rxBufferCount = SPI1STATbits.RXBUFELM;
if (spi_data_ptr->inBufferLen + rxBufferCount < SPI1_BUFFER_SIZE) {
for (i = 0; i < rxBufferCount; i++) {
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
for (i = 0; i < rxBufferCount; i++) {
int tmp = SPI1BUF;
}
for (i = 0; i < rxBufferCount; i++) {
char c = SPI1BUF;
// Call the RX callback function on the received data
if (spi_data_ptr->rx_callback != NULL)
(*spi_data_ptr->rx_callback)(c);
}
IFS0CLR = 0x01000000; // Clear the RX flag
}
128,25 → 94,25
if (IFS0bits.SPI1TXIF) {
int i;
// Disable the transmit interrupt if all data has been sent
if (spi_data_ptr->outBufferLen == 0) {
if (spi_data_ptr->buffer_out_len == 0) {
IEC0CLR=0x02000000;
if (spi_data_ptr->callback_function != NULL)
(*spi_data_ptr->callback_function)();
if (spi_data_ptr->tx_callback != NULL)
(*spi_data_ptr->tx_callback)();
} else {
// Start transmitting the data in the buffer
int txBufferFree = 16 - SPI1STATbits.TXBUFELM;
if (spi_data_ptr->outBufferLen > txBufferFree) {
if (spi_data_ptr->buffer_out_len > txBufferFree) {
for (i = 0; i < txBufferFree; i++) {
SPI1BUF = spi_data_ptr->outBuffer[spi_data_ptr->outBufferInd];
spi_data_ptr->outBufferInd--;
SPI1BUF = spi_data_ptr->buffer_out[spi_data_ptr->buffer_out_ind];
spi_data_ptr->buffer_out_ind--;
}
spi_data_ptr->outBufferLen -= txBufferFree;
spi_data_ptr->buffer_out_len -= txBufferFree;
} else {
for (i = 0; i < spi_data_ptr->outBufferLen; i++) {
SPI1BUF = spi_data_ptr->outBuffer[spi_data_ptr->outBufferInd];
spi_data_ptr->outBufferInd--;
for (i = 0; i < spi_data_ptr->buffer_out_len; i++) {
SPI1BUF = spi_data_ptr->buffer_out[spi_data_ptr->buffer_out_ind];
spi_data_ptr->buffer_out_ind--;
}
spi_data_ptr->outBufferLen = 0;
spi_data_ptr->buffer_out_len = 0;
}
}
IFS0CLR = 0x02000000; // Clear the TX flag