Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
147 Kevin 1
#include "defines.h"
121 Kevin 2
#include "spi.h"
3
 
4
static SPI_DATA spi_data;
128 Kevin 5
static SPI_DATA *spi_data_p = &spi_data;
121 Kevin 6
 
7
void SPI2_Init(unsigned char speed) {
8
    // Set up SPI2 with specified pins
147 Kevin 9
    RPINR22 = PPS_SPI2_CLK_IN; // SPI2 CLK Input
10
    PPS_SPI2_CLK_OUT = 11; // SPI2 CLK Output
121 Kevin 11
 
12
#ifndef SPI2_WRITE_ONLY
147 Kevin 13
    RPINR21 = PPS_SPI2_MISO; // SPI2 Data Input
14
    SPI_MISO_TRIS = 1; // SPI2 data in pin (MISO)
121 Kevin 15
#endif
147 Kevin 16
 
17
    SPI_CLK_TRIS = 0; // SPI2 clock pin
18
    PPS_SPI2_MOSI = 10; // SPI2 Data Output (MOSI)
19
    SPI_MOSI_TRIS = 0; // SPI2 data out pin (MOSI)
121 Kevin 20
 
147 Kevin 21
    SPI_SLAVE_SELECT_TRIS = 0; // SPI2 slave select
129 Kevin 22
    SPI_SLAVE_SELECT_LAT = 1; // SPI2 SS high (Idle)
121 Kevin 23
 
147 Kevin 24
    SPI_RESET_TRIS = 0; // SPI2 reset
129 Kevin 25
    SPI_RESET_LAT = 1; // SPI2 reset active low
121 Kevin 26
 
147 Kevin 27
    SPI_DC_SELECT_TRIS = 0; // SPI2 D/C select
129 Kevin 28
    SPI_DC_SELECT_LAT = 0;
121 Kevin 29
 
30
    SSP2STATbits.SMP = 0; // Input is sampled in the middle of data output time
31
    SSP2STATbits.CKE = 0; // Transmit occurs on transition from Idle to active clock state
32
 
123 Kevin 33
    SSP2CON1bits.SSPM = speed;
121 Kevin 34
 
35
    SSP2CON1bits.CKP = 1; // Idle state for clock is a high level
36
    SSP2CON1bits.SSPEN = 1; // Enable MSSP module
37
 
38
#ifdef SPI2_USE_INTERRUPT
39
    PIE3bits.SSP2IE = 1; // Enable MSSP2 interrupt
40
#else
41
    PIE3bits.SSP2IE = 0;
42
#endif
43
 
147 Kevin 44
#ifndef SPI2_WRITE_ONLY
128 Kevin 45
    spi_data_p->buffer_in_len = 0;
46
    spi_data_p->buffer_in_read_ind = 0;
47
    spi_data_p->buffer_in_write_ind = 0;
147 Kevin 48
#endif
128 Kevin 49
    spi_data_p->buffer_out_ind = 0;
50
    spi_data_p->buffer_out_len = 0;
121 Kevin 51
}
52
 
53
void SPI2_Write(unsigned char *msg, unsigned int length) {
54
#ifdef SPI2_USE_INTERRUPT
55
    unsigned char i;
128 Kevin 56
    spi_data_p->buffer_out_len = length;
57
    spi_data_p->buffer_out_ind = 1;
121 Kevin 58
    for (i = 0; i < length; i++) {
128 Kevin 59
        spi_data_p->buffer_out[i] = msg[i];
121 Kevin 60
    }
129 Kevin 61
    SPI_SLAVE_SELECT_LAT = 0; // Bring SS line low
128 Kevin 62
    SSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte
121 Kevin 63
#else
64
    unsigned int i = 0;
65
    unsigned char tmp = 0;
129 Kevin 66
    SPI_SLAVE_SELECT_LAT = 0;
121 Kevin 67
    while (i != length) {
68
        SSP2BUF = msg[i];
69
        i++;
70
        while (!SSP2STATbits.BF);
71
 
72
#ifndef SPI2_WRITE_ONLY
128 Kevin 73
        spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
74
        if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
75
            spi_data_p->buffer_in_write_ind = 0;
121 Kevin 76
        } else {
128 Kevin 77
            spi_data_p->buffer_in_write_ind++;
121 Kevin 78
        }
128 Kevin 79
        spi_data_p->buffer_in_len++;
121 Kevin 80
#else
81
        // Read data in buffer to clear it
82
        tmp = SSP2BUF;
83
#endif
84
    }
129 Kevin 85
    SPI_SLAVE_SELECT_LAT = 1;
121 Kevin 86
#endif
87
}
88
 
89
void SPI2_Write_Repeat(unsigned char c, unsigned int length) {
90
#ifdef SPI2_USE_INTERRUPT
147 Kevin 91
    // TODO Implement interrupts for SPI2
121 Kevin 92
#else
93
    unsigned int i = 0;
94
    unsigned char tmp = 0;
129 Kevin 95
    SPI_SLAVE_SELECT_LAT = 0;
121 Kevin 96
    while (i != length) {
97
        SSP2BUF = c;
98
        i++;
99
        while (!SSP2STATbits.BF);
100
 
101
#ifndef SPI2_WRITE_ONLY
128 Kevin 102
        spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
103
        if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
104
            spi_data_p->buffer_in_write_ind = 0;
121 Kevin 105
        } else {
128 Kevin 106
            spi_data_p->buffer_in_write_ind++;
121 Kevin 107
        }
128 Kevin 108
        spi_data_p->buffer_in_len++;
121 Kevin 109
#else
110
        // Read data in buffer to clear it
111
        tmp = SSP2BUF;
112
#endif
113
    }
129 Kevin 114
    SPI_SLAVE_SELECT_LAT = 1;
121 Kevin 115
#endif
116
}
117
 
147 Kevin 118
#ifndef SPI2_WRITE_ONLY
119
void SPI2_Recv_Interrupt_Handler() {
120
    unsigned char c;
121
 
122
    if (SSP2STATbits.BF) { // Check if data receive flag is set
123
        if (spi_data_p->buffer_in_len == MAXSPIBUF - 1) {
124
            DBG_PRINT_SPI("SPI2: (ERROR) buffer overflow\r\n");
125
            c = SSP2BUF; // Read SSP2BUF to clear it
126
        } else {
127
            // Save received data into buffer
128
            spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
129
            if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
130
                spi_data_p->buffer_in_write_ind = 0;
131
            } else {
132
                spi_data_p->buffer_in_write_ind++;
133
            }
134
            spi_data_p->buffer_in_len++;
135
 
136
            // Put next byte in SSP2BUF for transmit
137
            if (spi_data_p->buffer_out_ind != spi_data_p->buffer_out_len) {
138
                SSP2BUF = spi_data_p->buffer_out[spi_data_p->buffer_out_ind];
139
                spi_data_p->buffer_out_ind++;
140
            } else {
141
                SPI_SLAVE_SELECT_LAT = 1; // Bring SS line high
142
                spi_data_p->buffer_out_ind = 0;
143
                spi_data_p->buffer_out_len = 0;
144
            }
145
        }
146
    }
147
}
148
 
121 Kevin 149
void SPI2_Read(unsigned char length) {
150
#ifdef SPI2_USE_INTERRUPT
151
    unsigned char i;
128 Kevin 152
    spi_data_p->buffer_out_len = length;
153
    spi_data_p->buffer_out_ind = 1;
121 Kevin 154
    for (i = 0; i < length; i++) {
128 Kevin 155
        spi_data_p->buffer_out[i] = 0x0;
121 Kevin 156
    }
129 Kevin 157
    SPI_SLAVE_SELECT_LAT = 0; // Bring SS line low
128 Kevin 158
    SSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte
121 Kevin 159
#else
160
    unsigned char i = 0;
129 Kevin 161
    SPI_SLAVE_SELECT_LAT = 0;
121 Kevin 162
 
163
    for (i = 0; i < length; i++) {
164
        SSP2BUF = 0x0;
165
        while (!SSP2STATbits.BF);
166
 
128 Kevin 167
        spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
168
        if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
169
            spi_data_p->buffer_in_write_ind = 0;
121 Kevin 170
        } else {
128 Kevin 171
            spi_data_p->buffer_in_write_ind++;
121 Kevin 172
        }
128 Kevin 173
        spi_data_p->buffer_in_len++;
121 Kevin 174
    }
129 Kevin 175
    SPI_SLAVE_SELECT_LAT = 1;
121 Kevin 176
#endif
177
}
178
 
179
unsigned char SPI2_Buffer_Len() {
128 Kevin 180
    return spi_data_p->buffer_in_len;
121 Kevin 181
}
182
 
183
unsigned char SPI2_Buffer_Read(unsigned char* buffer) {
184
    unsigned char i = 0;
128 Kevin 185
    while (spi_data_p->buffer_in_len != 0) {
186
        buffer[i] = spi_data_p->buffer_in[spi_data_p->buffer_in_read_ind];
121 Kevin 187
        i++;
128 Kevin 188
        if (spi_data_p->buffer_in_read_ind == MAXSPIBUF - 1) {
189
            spi_data_p->buffer_in_read_ind = 0;
121 Kevin 190
        } else {
128 Kevin 191
            spi_data_p->buffer_in_read_ind++;
121 Kevin 192
        }
128 Kevin 193
        spi_data_p->buffer_in_len--;
121 Kevin 194
    }
195
    return i;
147 Kevin 196
}
197
#endif