Rev 147 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#include "defines.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 = PPS_SPI2_CLK_IN; // SPI2 CLK InputPPS_SPI2_CLK_OUT = 11; // SPI2 CLK Output#ifndef SPI2_WRITE_ONLYRPINR21 = PPS_SPI2_MISO; // SPI2 Data InputSPI_MISO_TRIS = 1; // SPI2 data in pin (MISO)#endifSPI_CLK_TRIS = 0; // SPI2 clock pinPPS_SPI2_MOSI = 10; // SPI2 Data Output (MOSI)SPI_MOSI_TRIS = 0; // SPI2 data out pin (MOSI)SPI_SLAVE_SELECT_TRIS = 0; // SPI2 slave selectSPI_SLAVE_SELECT_LAT = 1; // SPI2 SS high (Idle)SPI_RESET_TRIS = 0; // SPI2 resetSPI_RESET_LAT = 1; // SPI2 reset active lowSPI_DC_SELECT_TRIS = 0; // SPI2 D/C selectSPI_DC_SELECT_LAT = 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;SSP2CON1bits.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;#endif#ifndef SPI2_WRITE_ONLYspi_data_p->buffer_in_len = 0;spi_data_p->buffer_in_read_ind = 0;spi_data_p->buffer_in_write_ind = 0;#endifspi_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];}SPI_SLAVE_SELECT_LAT = 0; // Bring SS line lowSSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte#elseunsigned int i = 0;unsigned char tmp = 0;SPI_SLAVE_SELECT_LAT = 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}SPI_SLAVE_SELECT_LAT = 1;#endif}void SPI2_Write_Repeat(unsigned char c, unsigned int length) {#ifdef SPI2_USE_INTERRUPT// TODO Implement interrupts for SPI2#elseunsigned int i = 0;unsigned char tmp = 0;SPI_SLAVE_SELECT_LAT = 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}SPI_SLAVE_SELECT_LAT = 1;#endif}#ifndef SPI2_WRITE_ONLYvoid 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 {SPI_SLAVE_SELECT_LAT = 1; // Bring SS line highspi_data_p->buffer_out_ind = 0;spi_data_p->buffer_out_len = 0;}}}}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;}SPI_SLAVE_SELECT_LAT = 0; // Bring SS line lowSSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte#elseunsigned char i = 0;SPI_SLAVE_SELECT_LAT = 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++;}SPI_SLAVE_SELECT_LAT = 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;}#endif