Rev 231 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#include "defines.h"#include "SPI1.h"static SPI1_DATA *spi_data_ptr;void SPI1_Init(SPI1_DATA *data, void (*rx_callback)(uint8_t)) {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.uint32_t 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();}uint8_t SPI1_Write(uint8_t *array, uint32_t length, void (*tx_callback)(void)) {spi_data_ptr->tx_callback = tx_callback;if (length > SPI1_BUFFER_OUT_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 = length;spi_data_ptr->buffer_out_ind = length-1;int32_t i;for (i = 0; i < length; 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) {int32_t i;// Read the data received from the last transferint32_t rxBufferCount = SPI1STATbits.RXBUFELM;for (i = 0; i < rxBufferCount; i++) {int8_t 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) {int32_t 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 bufferint32_t 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}}