Rev 123 | Blame | Last modification | View Log | Download | RSS feed
#include "maindefs.h"#include "spi.h"static SPI_DATA spi_data;static SPI_DATA *spi_data_p = &spi_data;void SPI2_Init(unsigned char speed) {// Set up SPI2 with specified pinsRPINR22 = 7; // SPI2 CLK Input (Pin RB4)RPOR7 = 11; // SPI2 CLK Output (Pin RB4)#ifndef SPI2_WRITE_ONLYRPINR21 = 6; // SPI2 Data Input (Pin RB3)#endifRPOR5 = 10; // SPI2 Data Output (MOSI) (Pin RB2)TRISBbits.TRISB4 = 0; // SPI2 clock pin (Pin RB4)#ifndef SPI2_WRITE_ONLYTRISBbits.TRISB3 = 1; // SPI2 data in pin (Pin RB3)(MISO)#endifTRISBbits.TRISB2 = 0; // SPI2 data out pin (Pin RB2)(MOSI)TRISBbits.TRISB7 = 0; // SPI2 slave select (Pin RB7)LATBbits.LATB7 = 1; // SPI2 SS high (Idle)TRISBbits.TRISB6 = 0; // SPI2 reset (Pin RB6)LATBbits.LATB6 = 1; // SPI2 reset active lowTRISBbits.TRISB5 = 0; // SPI2 D/C select (Pin RB5)LATBbits.LATB5 = 0;SSP2STATbits.SMP = 0; // Input is sampled in the middle of data output timeSSP2STATbits.CKE = 0; // Transmit occurs on transition from Idle to active clock stateSSP2CON1bits.SSPM = speed;// if (speed == SPI2_FOSC_4)// SSP2CON1bits.SSPM = 0b0000; // Clock = FOSC/4// else if (speed == SPI2_FOSC_8)// SSP2CON1bits.SSPM = 0b1010; // Clock = FOSC/8// else if (speed == SPI2_FOSC_16)// SSP2CON1bits.SSPM = 0b0001; // Clock = FOSC/16// else// SSP2CON1bits.SSPM = 0b0010; // Clock = FOSC/64SSP2CON1bits.CKP = 1; // Idle state for clock is a high levelSSP2CON1bits.SSPEN = 1; // Enable MSSP module#ifdef SPI2_USE_INTERRUPTPIE3bits.SSP2IE = 1; // Enable MSSP2 interrupt#elsePIE3bits.SSP2IE = 0;#endifspi_data_p->buffer_in_len = 0;spi_data_p->buffer_in_read_ind = 0;spi_data_p->buffer_in_write_ind = 0;spi_data_p->buffer_out_ind = 0;spi_data_p->buffer_out_len = 0;}void SPI2_Recv_Interrupt_Handler() {unsigned char c;if (SSP2STATbits.BF) { // Check if data receive flag is setif (spi_data_p->buffer_in_len == MAXSPIBUF - 1) {DBG_PRINT_SPI("SPI2: (ERROR) buffer overflow\r\n");c = SSP2BUF; // Read SSP2BUF to clear it} else {// Save received data into bufferspi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {spi_data_p->buffer_in_write_ind = 0;} else {spi_data_p->buffer_in_write_ind++;}spi_data_p->buffer_in_len++;// Put next byte in SSP2BUF for transmitif (spi_data_p->buffer_out_ind != spi_data_p->buffer_out_len) {SSP2BUF = spi_data_p->buffer_out[spi_data_p->buffer_out_ind];spi_data_p->buffer_out_ind++;} else {LATBbits.LATB2 = 1; // Bring SS line highspi_data_p->buffer_out_ind = 0;spi_data_p->buffer_out_len = 0;}}}}void SPI2_Write(unsigned char *msg, unsigned int length) {#ifdef SPI2_USE_INTERRUPTunsigned char i;spi_data_p->buffer_out_len = length;spi_data_p->buffer_out_ind = 1;for (i = 0; i < length; i++) {spi_data_p->buffer_out[i] = msg[i];}LATBbits.LATB7 = 0; // Bring SS line lowSSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte#elseunsigned int i = 0;unsigned char tmp = 0;LATBbits.LATB7 = 0;while (i != length) {SSP2BUF = msg[i];i++;while (!SSP2STATbits.BF);#ifndef SPI2_WRITE_ONLYspi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {spi_data_p->buffer_in_write_ind = 0;} else {spi_data_p->buffer_in_write_ind++;}spi_data_p->buffer_in_len++;#else// Read data in buffer to clear ittmp = SSP2BUF;#endif}LATBbits.LATB7 = 1;#endif}void SPI2_Write_Repeat(unsigned char c, unsigned int length) {#ifdef SPI2_USE_INTERRUPT// TODO#elseunsigned int i = 0;unsigned char tmp = 0;LATBbits.LATB7 = 0;while (i != length) {SSP2BUF = c;i++;while (!SSP2STATbits.BF);#ifndef SPI2_WRITE_ONLYspi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {spi_data_p->buffer_in_write_ind = 0;} else {spi_data_p->buffer_in_write_ind++;}spi_data_p->buffer_in_len++;#else// Read data in buffer to clear ittmp = SSP2BUF;#endif}LATBbits.LATB7 = 1;#endif}void SPI2_Read(unsigned char length) {#ifdef SPI2_USE_INTERRUPTunsigned char i;spi_data_p->buffer_out_len = length;spi_data_p->buffer_out_ind = 1;for (i = 0; i < length; i++) {spi_data_p->buffer_out[i] = 0x0;}LATBbits.LATB7 = 0; // Bring SS line lowSSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte#elseunsigned char i = 0;LATBbits.LATB7 = 0;for (i = 0; i < length; i++) {SSP2BUF = 0x0;while (!SSP2STATbits.BF);spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {spi_data_p->buffer_in_write_ind = 0;} else {spi_data_p->buffer_in_write_ind++;}spi_data_p->buffer_in_len++;}LATBbits.LATB7 = 1;#endif}unsigned char SPI2_Buffer_Len() {return spi_data_p->buffer_in_len;}unsigned char SPI2_Buffer_Read(unsigned char* buffer) {unsigned char i = 0;while (spi_data_p->buffer_in_len != 0) {buffer[i] = spi_data_p->buffer_in[spi_data_p->buffer_in_read_ind];i++;if (spi_data_p->buffer_in_read_ind == MAXSPIBUF - 1) {spi_data_p->buffer_in_read_ind = 0;} else {spi_data_p->buffer_in_read_ind++;}spi_data_p->buffer_in_len--;}return i;}