Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

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