Rev 212 | Rev 226 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#include <xc.h>#include <plib.h>#include "defines.h"#include "SPI1.h"static SPI1_DATA *spi_data_ptr;void SPI1_Init(SPI1_DATA *data, void (*rx_callback)(char)) {spi_data_ptr = data;spi_data_ptr->buffer_out_ind = 0;spi_data_ptr->buffer_out_len = 0;spi_data_ptr->rx_callback = rx_callback;INTDisableInterrupts();// Note: FIFO enhanced buffer depth is 4/8/16 for 32/16/8 bit widths// Alternative Configuration:// The third value is the SPI bitrate which is 1/2 the frequency of the// desired clock frequency. Thus 40Mhz / (20Mhz / 2) = 4.// Note: SPI_OPEN_TBE_NOT_FULL should only be used at >10Mhz speeds// SpiChnOpen(SPI_CHANNEL1, SPI_OPEN_MSTEN | SPI_OPEN_ENHBUF | SPI_OPEN_TBE_NOT_FULL | SPI_OPEN_RBF_NOT_EMPTY, 4);// INTSetVectorPriority(INT_SPI_1_VECTOR, INT_PRIORITY_LEVEL_6);// INTSetVectorSubPriority(INT_SPI_1_VECTOR, INT_SUB_PRIORITY_LEVEL_1);// INTClearFlag(INT_SPI1E);// INTClearFlag(INT_SPI1TX);// INTClearFlag(INT_SPI1RX);// FSCK = FPB / (2 * (SPIxBRG + 1))IEC0CLR = 0x03800000; // Disable all SPI interruptsSPI1CON = 0; // Stops and resets the SPI1.int tmp = SPI1BUF; // Clears the receive bufferIFS0CLR = 0x03800000; // Clear any existing eventIPC5CLR = 0x1F000000; // Clear the priorityIPC5SET = 0x19000000; // Set IPL=6, Subpriority 1SPI1BRG = 0x1; // Use FPB/4 clock frequencySPI1STATCLR = 0x40; // Clear the Overflow#ifndef SPI_WRITE_ONLYIEC0SET = 0x01800000; // Enable RX and Error interrupts#endif// Enhanced buffer, SPI on, 8 bits transfer, SMP=1, Master mode// SPIxTXIF set on buffer empty, SPIxRXIF set on buffer not emptySPI1CON = 0x18225;INTEnableInterrupts();}int SPI1_Write(unsigned char *array, unsigned int count, void (*tx_callback)(void)) {spi_data_ptr->tx_callback = tx_callback;if (count > SPI1_BUFFER_SIZE)return 0;if (spi_data_ptr->buffer_out_len != 0)return 0;// Put the data to send into the outbound bufferspi_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->buffer_out[i] = array[i];}IEC0SET = 0x02000000; // Enable TX interruptreturn 1;}void __ISR(_SPI_1_VECTOR, ipl6) __SPI_1_Interrupt_Handler(void) {#ifndef SPI_WRITE_ONLY// Process SPI1 error flagif (IFS0bits.SPI1EIF) {// Clear the receive overflow bit if it is setif (SPI1STATbits.SPIROV) {SPI1STATbits.SPIROV = 0;}IFS0CLR = 0x00800000; // Clear the error flag}// Process SPI1 receive flagif (IFS0bits.SPI1RXIF) {int i;// Read the data received from the last transferint rxBufferCount = SPI1STATbits.RXBUFELM;for (i = 0; i < rxBufferCount; i++) {char c = SPI1BUF;// Call the RX callback function on the received dataif (spi_data_ptr->rx_callback != NULL)(*spi_data_ptr->rx_callback)(c);}IFS0CLR = 0x01000000; // Clear the RX flag}#endif// Process SPI1 transmit flagif (IFS0bits.SPI1TXIF && IEC0bits.SPI1TXIE) {int i;// Disable the transmit interrupt if all data has been sentif (spi_data_ptr->buffer_out_len == 0) {IEC0CLR=0x02000000;if (spi_data_ptr->tx_callback != NULL)(*spi_data_ptr->tx_callback)();} else {// Start transmitting the data in the bufferint txBufferFree = 16 - SPI1STATbits.TXBUFELM;if (spi_data_ptr->buffer_out_len > txBufferFree) {for (i = 0; i < txBufferFree; i++) {SPI1BUF = spi_data_ptr->buffer_out[spi_data_ptr->buffer_out_ind];spi_data_ptr->buffer_out_ind--;}spi_data_ptr->buffer_out_len -= txBufferFree;} else {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->buffer_out_len = 0;}}IFS0CLR = 0x02000000; // Clear the TX flag}}