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