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
129 Kevin 9
    RPINR22 = PPS_SPI2_CLK_IN; // SPI2 CLK Input  (Pin RB4)
10
    PPS_SPI2_CLK_OUT = 11; // SPI2 CLK Output (Pin RB4)
121 Kevin 11
#ifndef SPI2_WRITE_ONLY
129 Kevin 12
    RPINR21 = PPS_SPI2_MISO; // SPI2 Data Input (Pin RB3)
121 Kevin 13
#endif
129 Kevin 14
    PPS_SPI2_MOSI = 10; // SPI2 Data Output   (MOSI) (Pin RB2)
121 Kevin 15
 
129 Kevin 16
    SPI_CLK_TRIS = 0; // SPI2 clock pin       (Pin RB4)
121 Kevin 17
#ifndef SPI2_WRITE_ONLY
129 Kevin 18
    SPI_MISO_TRIS = 1; // SPI2 data in pin     (Pin RB3)(MISO)
121 Kevin 19
#endif
129 Kevin 20
    SPI_MOSI_TRIS = 0; // SPI2 data out pin    (Pin RB2)(MOSI)
121 Kevin 21
 
129 Kevin 22
    SPI_SLAVE_SELECT_TRIS = 0; // SPI2 slave select    (Pin RB7)
23
    SPI_SLAVE_SELECT_LAT = 1; // SPI2 SS high (Idle)
121 Kevin 24
 
129 Kevin 25
    SPI_RESET_TRIS = 0; // SPI2 reset   (Pin RB6)
26
    SPI_RESET_LAT = 1; // SPI2 reset active low
121 Kevin 27
 
129 Kevin 28
    SPI_DC_SELECT_TRIS = 0; // SPI2 D/C select (Pin RB5)
29
    SPI_DC_SELECT_LAT = 0;
121 Kevin 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;
121 Kevin 35
 
36
    SSP2CON1bits.CKP = 1; // Idle state for clock is a high level
37
    SSP2CON1bits.SSPEN = 1; // Enable MSSP module
38
 
39
#ifdef SPI2_USE_INTERRUPT
40
    PIE3bits.SSP2IE = 1; // Enable MSSP2 interrupt
41
#else
42
    PIE3bits.SSP2IE = 0;
43
#endif
44
 
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;
48
    spi_data_p->buffer_out_ind = 0;
49
    spi_data_p->buffer_out_len = 0;
121 Kevin 50
}
51
 
52
void SPI2_Recv_Interrupt_Handler() {
53
    unsigned char c;
54
 
55
    if (SSP2STATbits.BF) { // Check if data receive flag is set
128 Kevin 56
        if (spi_data_p->buffer_in_len == MAXSPIBUF - 1) {
122 Kevin 57
            DBG_PRINT_SPI("SPI2: (ERROR) buffer overflow\r\n");
121 Kevin 58
            c = SSP2BUF; // Read SSP2BUF to clear it
59
        } else {
60
            // Save received data into buffer
128 Kevin 61
            spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
62
            if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
63
                spi_data_p->buffer_in_write_ind = 0;
121 Kevin 64
            } else {
128 Kevin 65
                spi_data_p->buffer_in_write_ind++;
121 Kevin 66
            }
128 Kevin 67
            spi_data_p->buffer_in_len++;
121 Kevin 68
 
69
            // Put next byte in SSP2BUF for transmit
128 Kevin 70
            if (spi_data_p->buffer_out_ind != spi_data_p->buffer_out_len) {
71
                SSP2BUF = spi_data_p->buffer_out[spi_data_p->buffer_out_ind];
72
                spi_data_p->buffer_out_ind++;
121 Kevin 73
            } else {
129 Kevin 74
                SPI_SLAVE_SELECT_LAT = 1; // Bring SS line high
128 Kevin 75
                spi_data_p->buffer_out_ind = 0;
76
                spi_data_p->buffer_out_len = 0;
121 Kevin 77
            }
78
        }
79
    }
80
}
81
 
82
void SPI2_Write(unsigned char *msg, unsigned int length) {
83
#ifdef SPI2_USE_INTERRUPT
84
    unsigned char i;
128 Kevin 85
    spi_data_p->buffer_out_len = length;
86
    spi_data_p->buffer_out_ind = 1;
121 Kevin 87
    for (i = 0; i < length; i++) {
128 Kevin 88
        spi_data_p->buffer_out[i] = msg[i];
121 Kevin 89
    }
129 Kevin 90
    SPI_SLAVE_SELECT_LAT = 0; // Bring SS line low
128 Kevin 91
    SSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte
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 = msg[i];
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
 
118
void SPI2_Write_Repeat(unsigned char c, unsigned int length) {
119
#ifdef SPI2_USE_INTERRUPT
120
    // TODO
121
#else
122
    unsigned int i = 0;
123
    unsigned char tmp = 0;
129 Kevin 124
    SPI_SLAVE_SELECT_LAT = 0;
121 Kevin 125
    while (i != length) {
126
        SSP2BUF = c;
127
        i++;
128
        while (!SSP2STATbits.BF);
129
 
130
#ifndef SPI2_WRITE_ONLY
128 Kevin 131
        spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
132
        if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
133
            spi_data_p->buffer_in_write_ind = 0;
121 Kevin 134
        } else {
128 Kevin 135
            spi_data_p->buffer_in_write_ind++;
121 Kevin 136
        }
128 Kevin 137
        spi_data_p->buffer_in_len++;
121 Kevin 138
#else
139
        // Read data in buffer to clear it
140
        tmp = SSP2BUF;
141
#endif
142
    }
129 Kevin 143
    SPI_SLAVE_SELECT_LAT = 1;
121 Kevin 144
#endif
145
}
146
 
147
void SPI2_Read(unsigned char length) {
148
#ifdef SPI2_USE_INTERRUPT
149
    unsigned char i;
128 Kevin 150
    spi_data_p->buffer_out_len = length;
151
    spi_data_p->buffer_out_ind = 1;
121 Kevin 152
    for (i = 0; i < length; i++) {
128 Kevin 153
        spi_data_p->buffer_out[i] = 0x0;
121 Kevin 154
    }
129 Kevin 155
    SPI_SLAVE_SELECT_LAT = 0; // Bring SS line low
128 Kevin 156
    SSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte
121 Kevin 157
#else
158
    unsigned char i = 0;
129 Kevin 159
    SPI_SLAVE_SELECT_LAT = 0;
121 Kevin 160
 
161
    for (i = 0; i < length; i++) {
162
        SSP2BUF = 0x0;
163
        while (!SSP2STATbits.BF);
164
 
128 Kevin 165
        spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
166
        if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
167
            spi_data_p->buffer_in_write_ind = 0;
121 Kevin 168
        } else {
128 Kevin 169
            spi_data_p->buffer_in_write_ind++;
121 Kevin 170
        }
128 Kevin 171
        spi_data_p->buffer_in_len++;
121 Kevin 172
    }
129 Kevin 173
    SPI_SLAVE_SELECT_LAT = 1;
121 Kevin 174
#endif
175
}
176
 
177
unsigned char SPI2_Buffer_Len() {
128 Kevin 178
    return spi_data_p->buffer_in_len;
121 Kevin 179
}
180
 
181
unsigned char SPI2_Buffer_Read(unsigned char* buffer) {
182
    unsigned char i = 0;
128 Kevin 183
    while (spi_data_p->buffer_in_len != 0) {
184
        buffer[i] = spi_data_p->buffer_in[spi_data_p->buffer_in_read_ind];
121 Kevin 185
        i++;
128 Kevin 186
        if (spi_data_p->buffer_in_read_ind == MAXSPIBUF - 1) {
187
            spi_data_p->buffer_in_read_ind = 0;
121 Kevin 188
        } else {
128 Kevin 189
            spi_data_p->buffer_in_read_ind++;
121 Kevin 190
        }
128 Kevin 191
        spi_data_p->buffer_in_len--;
121 Kevin 192
    }
193
    return i;
194
}