Rev 315 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#include "defines.h"#include "SPI.h"static SPI_DATA *spi_data_p;void SPI_Init(SPI_DATA *data, uint8_t speed) {spi_data_p = data;SPI_MOSI_TRIS = 0;SPI_CLK_TRIS = 0;#ifndef SPI_WRITE_ONLYSPI_MISO_TRIS = 1;#endif// SPI_SLAVE_SELECT_TRIS = 0; // SPI2 slave select// SPI_SLAVE_SELECT_LAT = 1; // SPI2 SS high (Idle)// SPI_RESET_TRIS = 0; // SPI2 reset// SPI_RESET_LAT = 1; // SPI2 reset active lowSPI_DC_SELECT_TRIS = 0; // SPI2 D/C selectSPI_DC_SELECT_LAT = 0;SSP1STATbits.SMP = 0; // Input is sampled in the middle of data output timeSSP1STATbits.CKE = 0; // Transmit occurs on transition from Idle to active clock stateSSP1CON1bits.SSPM = speed;SSP1CON1bits.CKP = 1; // Idle state for clock is a high levelSSP1CON1bits.SSPEN = 1; // Enable MSSP modulePIE1bits.SSP1IE = 0; // Disable MSSP interrupt#ifndef SPI_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 SPI_Write(uint8_t *msg, uint16_t length) {uint16_t i = 0;// SPI_SLAVE_SELECT_LAT = 0;while (i != length) {SSP1BUF = msg[i];i++;while (!SSP1STATbits.BF);#ifndef SPI_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 ituint8_t tmp = SSP1BUF;#endif}// SPI_SLAVE_SELECT_LAT = 1;}void SPI2_Write_Repeat(uint8_t c, uint16_t length) {uint16_t i = 0;// SPI_SLAVE_SELECT_LAT = 0;while (i != length) {SSP1BUF = c;i++;while (!SSP1STATbits.BF);#ifndef SPI_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 ituint8_t tmp = SSP1BUF;#endif}// SPI_SLAVE_SELECT_LAT = 1;}#ifndef SPI_WRITE_ONLYvoid SPI_Recv_Interrupt_Handler() {uint8_t c;if (SSP1STATbits.BF) { // Check if data receive flag is setif (spi_data_p->buffer_in_len == MAX_SPI_BUFFER - 1) {c = SSP1BUF; // Read SSP2BUF to clear it} else {// Save received data into bufferspi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP1BUF;if (spi_data_p->buffer_in_write_ind == MAX_SPI_BUFFER - 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) {SSP1BUF = 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 SPI_Read(char length) {// SPI_SLAVE_SELECT_LAT = 0;for (uint8_t i = 0; i < length; i++) {SSP1BUF = 0x0;while (!SSP1STATbits.BF);spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP1BUF;if (spi_data_p->buffer_in_write_ind == MAX_SPI_BUFFER - 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;}uint8_t SPI_Buffer_Len() {return spi_data_p->buffer_in_len;}uint8_t SPI_Read_Buffer(uint8_t* buffer) {uint8_t 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 == MAX_SPI_BUFFER - 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