Subversion Repositories Code-Repo

Rev

Rev 122 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 122 Rev 128
Line 1... Line 1...
1
#include "maindefs.h"
1
#include "maindefs.h"
2
#include "i2c.h"
2
#include "i2c.h"
3
 
3
 
4
static I2C_DATA i2c_data;
4
static I2C_DATA i2c_data;
-
 
5
static I2C_DATA *i2c_data_p = &i2c_data;
5
 
6
 
6
// Set up the data structures for the i2c code
7
// Set up the data structures for the i2c code
7
// Should be called once before any i2c routines are called
8
// Should be called once before any i2c routines are called
8
void I2C_Init() {
9
void I2C_Init() {
9
    i2c_data.buffer_in_len = 0;
10
    i2c_data_p->buffer_in_len = 0;
10
    i2c_data.buffer_in_len_tmp = 0;
11
    i2c_data_p->buffer_in_len_tmp = 0;
11
    i2c_data.buffer_in_read_ind = 0;
12
    i2c_data_p->buffer_in_read_ind = 0;
12
    i2c_data.buffer_in_write_ind = 0;
13
    i2c_data_p->buffer_in_write_ind = 0;
13
 
14
 
14
    i2c_data.buffer_out_ind = 0;
15
    i2c_data_p->buffer_out_ind = 0;
15
    i2c_data.buffer_out_len = 0;
16
    i2c_data_p->buffer_out_len = 0;
16
    
17
    
17
    i2c_data.operating_mode = 0;
18
    i2c_data_p->operating_mode = 0;
18
    i2c_data.operating_state = I2C_IDLE;
19
    i2c_data_p->operating_state = I2C_IDLE;
19
    i2c_data.return_status = 0;
20
    i2c_data_p->return_status = 0;
20
 
21
 
21
    i2c_data.slave_in_last_byte = 0;
22
    i2c_data_p->slave_in_last_byte = 0;
22
    i2c_data.slave_sending_data = 0;
23
    i2c_data_p->slave_sending_data = 0;
23
 
24
 
24
    i2c_data.master_dest_addr = 0;
25
    i2c_data_p->master_dest_addr = 0;
25
    i2c_data.master_status = I2C_MASTER_IDLE;
26
    i2c_data_p->master_status = I2C_MASTER_IDLE;
26
    
27
    
27
    // Enable I2C interrupt
28
    // Enable I2C interrupt
28
    PIE1bits.SSPIE = 1;
29
    PIE1bits.SSPIE = 1;
29
}
30
}
30
 
31
 
31
// Setup the PIC to operate as a master.
32
// Setup the PIC to operate as a master.
32
void I2C_Configure_Master(unsigned char speed) {
33
void I2C_Configure_Master(unsigned char speed) {
33
    i2c_data.operating_mode = I2C_MODE_MASTER;
34
    i2c_data_p->operating_mode = I2C_MODE_MASTER;
34
 
35
 
35
    TRISCbits.TRISC3 = 1;
36
    TRISCbits.TRISC3 = 1;
36
    TRISCbits.TRISC4 = 1;
37
    TRISCbits.TRISC4 = 1;
37
 
38
 
38
    SSPSTAT = 0x0;
39
    SSPSTAT = 0x0;
Line 54... Line 55...
54
    if (length == 0)
55
    if (length == 0)
55
        return;
56
        return;
56
    
57
    
57
    // Copy message to send into buffer and save length/address
58
    // Copy message to send into buffer and save length/address
58
    for (i = 0; i < length; i++) {
59
    for (i = 0; i < length; i++) {
59
        i2c_data.buffer_in[i] = msg[i];
60
        i2c_data_p->buffer_in[i] = msg[i];
60
    }
61
    }
61
    i2c_data.buffer_in_len = length;
62
    i2c_data_p->buffer_in_len = length;
62
    i2c_data.master_dest_addr = address;
63
    i2c_data_p->master_dest_addr = address;
63
    i2c_data.buffer_in_read_ind = 0;
64
    i2c_data_p->buffer_in_read_ind = 0;
64
    i2c_data.buffer_in_write_ind = 0;
65
    i2c_data_p->buffer_in_write_ind = 0;
65
 
66
 
66
    // Change status to 'next' operation
67
    // Change status to 'next' operation
67
    i2c_data.operating_state = I2C_SEND_ADDR;
68
    i2c_data_p->operating_state = I2C_SEND_ADDR;
68
    i2c_data.master_status = I2C_MASTER_SEND;
69
    i2c_data_p->master_status = I2C_MASTER_SEND;
69
    
70
    
70
    // Generate start condition
71
    // Generate start condition
71
    SSPCON2bits.SEN = 1;
72
    SSPCON2bits.SEN = 1;
72
}
73
}
73
 
74
 
Line 75... Line 76...
75
void I2C_Master_Recv(unsigned char address, unsigned char length) {
76
void I2C_Master_Recv(unsigned char address, unsigned char length) {
76
    if (length == 0)
77
    if (length == 0)
77
        return;
78
        return;
78
 
79
 
79
    // Save length and address to get data from
80
    // Save length and address to get data from
80
    i2c_data.buffer_in_len = length;
81
    i2c_data_p->buffer_in_len = length;
81
    i2c_data.master_dest_addr = address;
82
    i2c_data_p->master_dest_addr = address;
82
    i2c_data.buffer_in_read_ind = 0;
83
    i2c_data_p->buffer_in_read_ind = 0;
83
    i2c_data.buffer_in_write_ind = 0;
84
    i2c_data_p->buffer_in_write_ind = 0;
84
 
85
 
85
    // Change status to 'next' operation
86
    // Change status to 'next' operation
86
    i2c_data.operating_state = I2C_SEND_ADDR;
87
    i2c_data_p->operating_state = I2C_SEND_ADDR;
87
    i2c_data.master_status = I2C_MASTER_RECV;
88
    i2c_data_p->master_status = I2C_MASTER_RECV;
88
    
89
    
89
    // Generate start condition
90
    // Generate start condition
90
    SSPCON2bits.SEN = 1;
91
    SSPCON2bits.SEN = 1;
91
}
92
}
92
 
93
 
Line 98... Line 99...
98
        I2C_Master_Send(address, 1, &c);
99
        I2C_Master_Send(address, 1, &c);
99
        return;
100
        return;
100
    }
101
    }
101
 
102
 
102
    // Save length and address to get data from
103
    // Save length and address to get data from
103
    i2c_data.buffer_in[0] = msg;
104
    i2c_data_p->buffer_in[0] = msg;
104
    i2c_data.buffer_in_len = length;
105
    i2c_data_p->buffer_in_len = length;
105
    i2c_data.master_dest_addr = address;
106
    i2c_data_p->master_dest_addr = address;
106
    i2c_data.buffer_in_read_ind = 0;
107
    i2c_data_p->buffer_in_read_ind = 0;
107
    i2c_data.buffer_in_write_ind = 0;
108
    i2c_data_p->buffer_in_write_ind = 0;
108
 
109
 
109
    // Change status to 'next' operation
110
    // Change status to 'next' operation
110
    i2c_data.operating_state = I2C_SEND_ADDR;
111
    i2c_data_p->operating_state = I2C_SEND_ADDR;
111
    i2c_data.master_status = I2C_MASTER_RESTART;
112
    i2c_data_p->master_status = I2C_MASTER_RESTART;
112
 
113
 
113
    // Generate start condition
114
    // Generate start condition
114
    SSPCON2bits.SEN = 1;
115
    SSPCON2bits.SEN = 1;
115
}
116
}
116
 
117
 
117
// Setup the PIC to operate as a slave. The address must not include the R/W bit
118
// Setup the PIC to operate as a slave. The address must not include the R/W bit
118
void I2C_Configure_Slave(unsigned char addr) {
119
void I2C_Configure_Slave(unsigned char addr) {
119
    i2c_data.operating_mode = I2C_MODE_SLAVE;
120
    i2c_data_p->operating_mode = I2C_MODE_SLAVE;
120
 
121
 
121
    // Ensure the two lines are set for input (we are a slave)
122
    // Ensure the two lines are set for input (we are a slave)
122
    TRISCbits.TRISC3 = 1;
123
    TRISCbits.TRISC3 = 1;
123
    TRISCbits.TRISC4 = 1;
124
    TRISCbits.TRISC4 = 1;
124
 
125
 
Line 133... Line 134...
133
    SSPCON1bits.SSPEN = 1;  // Enable MSSP Module
134
    SSPCON1bits.SSPEN = 1;  // Enable MSSP Module
134
}
135
}
135
 
136
 
136
void I2C_Interrupt_Handler() {
137
void I2C_Interrupt_Handler() {
137
    // Call interrupt depending on which mode we are operating in
138
    // Call interrupt depending on which mode we are operating in
138
    if (i2c_data.operating_mode == I2C_MODE_MASTER) {
139
    if (i2c_data_p->operating_mode == I2C_MODE_MASTER) {
139
        I2C_Interrupt_Master();
140
        I2C_Interrupt_Master();
140
    } else if (i2c_data.operating_mode == I2C_MODE_SLAVE) {
141
    } else if (i2c_data_p->operating_mode == I2C_MODE_SLAVE) {
141
        I2C_Interrupt_Slave();
142
        I2C_Interrupt_Slave();
142
    }
143
    }
143
}
144
}
144
 
145
 
145
// An internal subroutine used in the master version of the i2c_interrupt_handler
146
// An internal subroutine used in the master version of the i2c_interrupt_handler
146
void I2C_Interrupt_Master() {
147
void I2C_Interrupt_Master() {
147
    // If we are in the middle of sending data
148
    // If we are in the middle of sending data
148
    if (i2c_data.master_status == I2C_MASTER_SEND) {
149
    if (i2c_data_p->master_status == I2C_MASTER_SEND) {
149
        switch (i2c_data.operating_state) {
150
        switch (i2c_data_p->operating_state) {
150
            case I2C_IDLE:
151
            case I2C_IDLE:
151
                break;
152
                break;
152
            case I2C_SEND_ADDR:
153
            case I2C_SEND_ADDR:
153
                // Send the address with read bit set
154
                // Send the address with read bit set
154
                i2c_data.operating_state = I2C_CHECK_ACK_SEND;
155
                i2c_data_p->operating_state = I2C_CHECK_ACK_SEND;
155
                SSPBUF = (i2c_data.master_dest_addr << 1) | 0x0;
156
                SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x0;
156
                break;
157
                break;
157
            case I2C_CHECK_ACK_SEND:
158
            case I2C_CHECK_ACK_SEND:
158
                // Check if ACK is received or not
159
                // Check if ACK is received or not
159
                if (!SSPCON2bits.ACKSTAT) {
160
                if (!SSPCON2bits.ACKSTAT) {
160
                    // If an ACK is received, send next byte of data
161
                    // If an ACK is received, send next byte of data
161
                    if (i2c_data.buffer_in_read_ind < i2c_data.buffer_in_len) {
162
                    if (i2c_data_p->buffer_in_read_ind < i2c_data_p->buffer_in_len) {
162
                        SSPBUF = i2c_data.buffer_in[i2c_data.buffer_in_read_ind];
163
                        SSPBUF = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
163
                        i2c_data.buffer_in_read_ind++;
164
                        i2c_data_p->buffer_in_read_ind++;
164
                    } else {
165
                    } else {
165
                        // If no more data is to be sent, send stop bit
166
                        // If no more data is to be sent, send stop bit
166
                        i2c_data.operating_state = I2C_IDLE;
167
                        i2c_data_p->operating_state = I2C_IDLE;
167
                        SSPCON2bits.PEN = 1;
168
                        SSPCON2bits.PEN = 1;
168
                        i2c_data.master_status = I2C_MASTER_IDLE;
169
                        i2c_data_p->master_status = I2C_MASTER_IDLE;
169
                        i2c_data.return_status = I2C_SEND_OK;
170
                        i2c_data_p->return_status = I2C_SEND_OK;
170
                    }
171
                    }
171
                } else {
172
                } else {
172
                    // If a NACK is received, stop transmission and send error
173
                    // If a NACK is received, stop transmission and send error
173
                    i2c_data.operating_state = I2C_IDLE;
174
                    i2c_data_p->operating_state = I2C_IDLE;
174
                    SSPCON2bits.PEN = 1;
175
                    SSPCON2bits.PEN = 1;
175
                    i2c_data.master_status = I2C_MASTER_IDLE;
176
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
176
                    i2c_data.return_status = I2C_SEND_FAIL;
177
                    i2c_data_p->return_status = I2C_SEND_FAIL;
177
                }
178
                }
178
                break;
179
                break;
179
        }
180
        }
180
    // If we are in the middle of receiving data
181
    // If we are in the middle of receiving data
181
    } else if (i2c_data.master_status == I2C_MASTER_RECV) {
182
    } else if (i2c_data_p->master_status == I2C_MASTER_RECV) {
182
        switch (i2c_data.operating_state) {
183
        switch (i2c_data_p->operating_state) {
183
            case I2C_IDLE:
184
            case I2C_IDLE:
184
                break;
185
                break;
185
            case I2C_SEND_ADDR:
186
            case I2C_SEND_ADDR:
186
                // Send address with write bit set
187
                // Send address with write bit set
187
                i2c_data.operating_state = I2C_CHECK_ACK_RECV;
188
                i2c_data_p->operating_state = I2C_CHECK_ACK_RECV;
188
                SSPBUF = (i2c_data.master_dest_addr << 1) | 0x1;
189
                SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x1;
189
                break;
190
                break;
190
            case I2C_CHECK_ACK_RECV:
191
            case I2C_CHECK_ACK_RECV:
191
                // Check if ACK is received
192
                // Check if ACK is received
192
                if (!SSPCON2bits.ACKSTAT) {
193
                if (!SSPCON2bits.ACKSTAT) {
193
                    // If an ACK is received, set module to receive 1 byte of data
194
                    // If an ACK is received, set module to receive 1 byte of data
194
                    i2c_data.operating_state = I2C_RCV_DATA;
195
                    i2c_data_p->operating_state = I2C_RCV_DATA;
195
                    SSPCON2bits.RCEN = 1;
196
                    SSPCON2bits.RCEN = 1;
196
                } else {
197
                } else {
197
                    // If a NACK is received, stop transmission and send error
198
                    // If a NACK is received, stop transmission and send error
198
                    i2c_data.operating_state = I2C_IDLE;
199
                    i2c_data_p->operating_state = I2C_IDLE;
199
                    SSPCON2bits.PEN = 1;
200
                    SSPCON2bits.PEN = 1;
200
                    i2c_data.master_status = I2C_MASTER_IDLE;
201
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
201
                    i2c_data.return_status = I2C_RECV_FAIL;
202
                    i2c_data_p->return_status = I2C_RECV_FAIL;
202
                }
203
                }
203
                break;
204
                break;
204
            case I2C_RCV_DATA:
205
            case I2C_RCV_DATA:
205
                // On receive, save byte into buffer
206
                // On receive, save byte into buffer
206
                // TODO: handle i2c buffer overflow
207
                // TODO: handle i2c buffer overflow
207
                i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = SSPBUF;
208
                i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = SSPBUF;
208
                i2c_data.buffer_in_write_ind++;
209
                i2c_data_p->buffer_in_write_ind++;
209
                if (i2c_data.buffer_in_write_ind < i2c_data.buffer_in_len) {
210
                if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
210
                    // If we still need to read, send an ACK to the slave
211
                    // If we still need to read, send an ACK to the slave
211
                    i2c_data.operating_state = I2C_REQ_DATA;
212
                    i2c_data_p->operating_state = I2C_REQ_DATA;
212
                    SSPCON2bits.ACKDT = 0;  // ACK
213
                    SSPCON2bits.ACKDT = 0;  // ACK
213
                    SSPCON2bits.ACKEN = 1;
214
                    SSPCON2bits.ACKEN = 1;
214
                } else {
215
                } else {
215
                    // If we are done reading, send an NACK to the slave
216
                    // If we are done reading, send an NACK to the slave
216
                    i2c_data.operating_state = I2C_SEND_STOP;
217
                    i2c_data_p->operating_state = I2C_SEND_STOP;
217
                    SSPCON2bits.ACKDT = 1;  // NACK
218
                    SSPCON2bits.ACKDT = 1;  // NACK
218
                    SSPCON2bits.ACKEN = 1;
219
                    SSPCON2bits.ACKEN = 1;
219
                }
220
                }
220
                break;
221
                break;
221
            case I2C_REQ_DATA:
222
            case I2C_REQ_DATA:
222
                // Set module to receive one byte of data
223
                // Set module to receive one byte of data
223
                i2c_data.operating_state = I2C_RCV_DATA;
224
                i2c_data_p->operating_state = I2C_RCV_DATA;
224
                SSPCON2bits.RCEN = 1;
225
                SSPCON2bits.RCEN = 1;
225
                break;
226
                break;
226
            case I2C_SEND_STOP:
227
            case I2C_SEND_STOP:
227
                // Send the stop bit and copy message to send to Main()
228
                // Send the stop bit and copy message to send to Main()
228
                i2c_data.operating_state = I2C_IDLE;
229
                i2c_data_p->operating_state = I2C_IDLE;
229
                SSPCON2bits.PEN = 1;
230
                SSPCON2bits.PEN = 1;
230
                i2c_data.master_status = I2C_MASTER_IDLE;
231
                i2c_data_p->master_status = I2C_MASTER_IDLE;
231
                i2c_data.return_status = I2C_RECV_OK;
232
                i2c_data_p->return_status = I2C_RECV_OK;
232
                break;
233
                break;
233
        }
234
        }
234
    } else if (i2c_data.master_status == I2C_MASTER_RESTART) {
235
    } else if (i2c_data_p->master_status == I2C_MASTER_RESTART) {
235
        switch (i2c_data.operating_state) {
236
        switch (i2c_data_p->operating_state) {
236
            case I2C_IDLE:
237
            case I2C_IDLE:
237
                break;
238
                break;
238
            case I2C_SEND_ADDR:
239
            case I2C_SEND_ADDR:
239
                // Send the address with read bit set
240
                // Send the address with read bit set
240
                i2c_data.operating_state = I2C_CHECK_ACK_SEND;
241
                i2c_data_p->operating_state = I2C_CHECK_ACK_SEND;
241
                SSPBUF = (i2c_data.master_dest_addr << 1) | 0x0;
242
                SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x0;
242
                break;
243
                break;
243
            case I2C_CHECK_ACK_SEND:
244
            case I2C_CHECK_ACK_SEND:
244
                // Check if ACK is received or not
245
                // Check if ACK is received or not
245
                if (!SSPCON2bits.ACKSTAT) {
246
                if (!SSPCON2bits.ACKSTAT) {
246
                    // If an ACK is received, send first byte of data
247
                    // If an ACK is received, send first byte of data
247
                    SSPBUF = i2c_data.buffer_in[0];
248
                    SSPBUF = i2c_data_p->buffer_in[0];
248
                    i2c_data.operating_state = I2C_CHECK_ACK_RESTART;
249
                    i2c_data_p->operating_state = I2C_CHECK_ACK_RESTART;
249
                } else {
250
                } else {
250
                    // If a NACK is received, stop transmission and send error
251
                    // If a NACK is received, stop transmission and send error
251
                    i2c_data.operating_state = I2C_IDLE;
252
                    i2c_data_p->operating_state = I2C_IDLE;
252
                    SSPCON2bits.PEN = 1;
253
                    SSPCON2bits.PEN = 1;
253
                    i2c_data.master_status = I2C_MASTER_IDLE;
254
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
254
                    i2c_data.return_status = I2C_SEND_FAIL;
255
                    i2c_data_p->return_status = I2C_SEND_FAIL;
255
                }
256
                }
256
                break;
257
                break;
257
            case I2C_CHECK_ACK_RESTART:
258
            case I2C_CHECK_ACK_RESTART:
258
                if (!SSPCON2bits.ACKSTAT) {
259
                if (!SSPCON2bits.ACKSTAT) {
259
                    SSPCON2bits.RSEN = 1;
260
                    SSPCON2bits.RSEN = 1;
260
                    i2c_data.operating_state = I2C_SEND_ADDR_2;
261
                    i2c_data_p->operating_state = I2C_SEND_ADDR_2;
261
                } else {
262
                } else {
262
                    // If a NACK is received, stop transmission and send error
263
                    // If a NACK is received, stop transmission and send error
263
                    i2c_data.operating_state = I2C_IDLE;
264
                    i2c_data_p->operating_state = I2C_IDLE;
264
                    SSPCON2bits.PEN = 1;
265
                    SSPCON2bits.PEN = 1;
265
                    i2c_data.master_status = I2C_MASTER_IDLE;
266
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
266
                    i2c_data.return_status = I2C_SEND_FAIL;
267
                    i2c_data_p->return_status = I2C_SEND_FAIL;
267
                }
268
                }
268
                break;
269
                break;
269
            case I2C_SEND_ADDR_2:
270
            case I2C_SEND_ADDR_2:
270
                // Send the address with read bit set
271
                // Send the address with read bit set
271
                i2c_data.operating_state = I2C_CHECK_ACK_RECV;
272
                i2c_data_p->operating_state = I2C_CHECK_ACK_RECV;
272
                SSPBUF = (i2c_data.master_dest_addr << 1) | 0x1;
273
                SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x1;
273
                break;
274
                break;
274
            case I2C_CHECK_ACK_RECV:
275
            case I2C_CHECK_ACK_RECV:
275
                // Check if ACK is received
276
                // Check if ACK is received
276
                if (!SSPCON2bits.ACKSTAT) {
277
                if (!SSPCON2bits.ACKSTAT) {
277
                    // If an ACK is received, set module to receive 1 byte of data
278
                    // If an ACK is received, set module to receive 1 byte of data
278
                    i2c_data.operating_state = I2C_RCV_DATA;
279
                    i2c_data_p->operating_state = I2C_RCV_DATA;
279
                    SSPCON2bits.RCEN = 1;
280
                    SSPCON2bits.RCEN = 1;
280
                } else {
281
                } else {
281
                    // If a NACK is received, stop transmission and send error
282
                    // If a NACK is received, stop transmission and send error
282
                    i2c_data.operating_state = I2C_IDLE;
283
                    i2c_data_p->operating_state = I2C_IDLE;
283
                    SSPCON2bits.PEN = 1;
284
                    SSPCON2bits.PEN = 1;
284
                    i2c_data.master_status = I2C_MASTER_IDLE;
285
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
285
                    i2c_data.return_status = I2C_RECV_FAIL;
286
                    i2c_data_p->return_status = I2C_RECV_FAIL;
286
                }
287
                }
287
                break;
288
                break;
288
            case I2C_RCV_DATA:
289
            case I2C_RCV_DATA:
289
                // On receive, save byte into buffer
290
                // On receive, save byte into buffer
290
                // TODO: handle i2c buffer overflow
291
                // TODO: handle i2c buffer overflow
291
                i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = SSPBUF;
292
                i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = SSPBUF;
292
                i2c_data.buffer_in_write_ind++;
293
                i2c_data_p->buffer_in_write_ind++;
293
                if (i2c_data.buffer_in_write_ind < i2c_data.buffer_in_len) {
294
                if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
294
                    // If we still need to read, send an ACK to the slave
295
                    // If we still need to read, send an ACK to the slave
295
                    i2c_data.operating_state = I2C_REQ_DATA;
296
                    i2c_data_p->operating_state = I2C_REQ_DATA;
296
                    SSPCON2bits.ACKDT = 0;  // ACK
297
                    SSPCON2bits.ACKDT = 0;  // ACK
297
                    SSPCON2bits.ACKEN = 1;
298
                    SSPCON2bits.ACKEN = 1;
298
                } else {
299
                } else {
299
                    // If we are done reading, send an NACK to the slave
300
                    // If we are done reading, send an NACK to the slave
300
                    i2c_data.operating_state = I2C_SEND_STOP;
301
                    i2c_data_p->operating_state = I2C_SEND_STOP;
301
                    SSPCON2bits.ACKDT = 1;  // NACK
302
                    SSPCON2bits.ACKDT = 1;  // NACK
302
                    SSPCON2bits.ACKEN = 1;
303
                    SSPCON2bits.ACKEN = 1;
303
                }
304
                }
304
                break;
305
                break;
305
            case I2C_REQ_DATA:
306
            case I2C_REQ_DATA:
306
                // Set module to receive one byte of data
307
                // Set module to receive one byte of data
307
                i2c_data.operating_state = I2C_RCV_DATA;
308
                i2c_data_p->operating_state = I2C_RCV_DATA;
308
                SSPCON2bits.RCEN = 1;
309
                SSPCON2bits.RCEN = 1;
309
                break;
310
                break;
310
            case I2C_SEND_STOP:
311
            case I2C_SEND_STOP:
311
                // Send the stop bit and copy message to send to Main()
312
                // Send the stop bit and copy message to send to Main()
312
                i2c_data.operating_state = I2C_IDLE;
313
                i2c_data_p->operating_state = I2C_IDLE;
313
                SSPCON2bits.PEN = 1;
314
                SSPCON2bits.PEN = 1;
314
                i2c_data.master_status = I2C_MASTER_IDLE;
315
                i2c_data_p->master_status = I2C_MASTER_IDLE;
315
                i2c_data.return_status = I2C_RECV_OK;
316
                i2c_data_p->return_status = I2C_RECV_OK;
316
                break;
317
                break;
317
        }
318
        }
318
    }
319
    }
319
}
320
}
320
 
321
 
Line 329... Line 330...
329
        DBG_PRINT_I2C("I2C: (ERROR) overflow detected\r\n");
330
        DBG_PRINT_I2C("I2C: (ERROR) overflow detected\r\n");
330
        SSPCON1bits.SSPOV = 0;
331
        SSPCON1bits.SSPOV = 0;
331
        // We failed to read the buffer in time, so we know we
332
        // We failed to read the buffer in time, so we know we
332
        //  can't properly receive this message, just put us in the
333
        //  can't properly receive this message, just put us in the
333
        //  a state where we are looking for a new message
334
        //  a state where we are looking for a new message
334
        i2c_data.operating_state = I2C_IDLE;
335
        i2c_data_p->operating_state = I2C_IDLE;
335
        overrun_error = 1;
336
        overrun_error = 1;
336
        i2c_data.return_status = I2C_ERR_OVERRUN;
337
        i2c_data_p->return_status = I2C_ERR_OVERRUN;
337
    }
338
    }
338
 
339
 
339
    // Read SPPxBUF if it is full
340
    // Read SPPxBUF if it is full
340
    if (SSPSTATbits.BF == 1) {
341
    if (SSPSTATbits.BF == 1) {
341
        received_data = SSPBUF;
342
        received_data = SSPBUF;
342
//        DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF);
343
//        DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF);
343
        data_read_from_buffer = 1;
344
        data_read_from_buffer = 1;
344
    }
345
    }
345
 
346
 
346
    if (!overrun_error) {
347
    if (!overrun_error) {
347
        switch (i2c_data.operating_state) {
348
        switch (i2c_data_p->operating_state) {
348
            case I2C_IDLE:
349
            case I2C_IDLE:
349
            {
350
            {
350
                // Ignore anything except a start
351
                // Ignore anything except a start
351
                if (SSPSTATbits.S == 1) {
352
                if (SSPSTATbits.S == 1) {
352
                    i2c_data.buffer_in_len_tmp = 0;
353
                    i2c_data_p->buffer_in_len_tmp = 0;
353
                    i2c_data.operating_state = I2C_STARTED;
354
                    i2c_data_p->operating_state = I2C_STARTED;
354
//                    if (data_read_from_buffer) {
355
//                    if (data_read_from_buffer) {
355
//                        if (SSPSTATbits.D_A == 1) {
356
//                        if (SSPSTATbits.D_A == 1) {
356
//                            DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n");
357
//                            DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n");
357
//                            // This is bad because we got data and we wanted an address
358
//                            // This is bad because we got data and we wanted an address
358
//                            i2c_data.operating_state = I2C_IDLE;
359
//                            i2c_data_p->operating_state = I2C_IDLE;
359
//                            i2c_data.return_status = I2C_ERR_NOADDR;
360
//                            i2c_data_p->return_status = I2C_ERR_NOADDR;
360
//                        } else {
361
//                        } else {
361
//                            // Determine if we are sending or receiving data
362
//                            // Determine if we are sending or receiving data
362
//                            if (SSPSTATbits.R_W == 1) {
363
//                            if (SSPSTATbits.R_W == 1) {
363
//                                i2c_data.operating_state = I2C_SEND_DATA;
364
//                                i2c_data_p->operating_state = I2C_SEND_DATA;
364
//                            } else {
365
//                            } else {
365
//                                i2c_data.operating_state = I2C_RCV_DATA;
366
//                                i2c_data_p->operating_state = I2C_RCV_DATA;
366
//                            }
367
//                            }
367
//                        }
368
//                        }
368
//                    } else {
369
//                    } else {
369
//                        i2c_data.operating_state = I2C_STARTED;
370
//                        i2c_data_p->operating_state = I2C_STARTED;
370
//                    }
371
//                    }
371
                }
372
                }
372
                break;
373
                break;
373
            }
374
            }
374
            case I2C_STARTED:
375
            case I2C_STARTED:
375
            {
376
            {
376
                // In this case, we expect either an address or a stop bit
377
                // In this case, we expect either an address or a stop bit
377
                if (SSPSTATbits.P == 1) {
378
                if (SSPSTATbits.P == 1) {
378
                    // Return to idle mode
379
                    // Return to idle mode
379
                    i2c_data.operating_state = I2C_IDLE;
380
                    i2c_data_p->operating_state = I2C_IDLE;
380
                } else if (data_read_from_buffer) {
381
                } else if (data_read_from_buffer) {
381
                    if (SSPSTATbits.D_A == 0) {
382
                    if (SSPSTATbits.D_A == 0) {
382
                        // Address received
383
                        // Address received
383
                        if (SSPSTATbits.R_W == 0) {
384
                        if (SSPSTATbits.R_W == 0) {
384
                            // Slave write mode
385
                            // Slave write mode
385
                            i2c_data.operating_state = I2C_RCV_DATA;
386
                            i2c_data_p->operating_state = I2C_RCV_DATA;
386
                        } else {
387
                        } else {
387
                            // Slave read mode
388
                            // Slave read mode
388
                            i2c_data.operating_state = I2C_SEND_DATA;
389
                            i2c_data_p->operating_state = I2C_SEND_DATA;
389
                            // Process the first byte immediatly if sending data
390
                            // Process the first byte immediatly if sending data
390
                            goto send;
391
                            goto send;
391
                        }
392
                        }
392
                    } else {
393
                    } else {
393
                        DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
394
                        DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
394
                        i2c_data.operating_state = I2C_IDLE;
395
                        i2c_data_p->operating_state = I2C_IDLE;
395
                        i2c_data.return_status = I2C_ERR_NODATA;
396
                        i2c_data_p->return_status = I2C_ERR_NODATA;
396
                    }
397
                    }
397
                }
398
                }
398
                break;
399
                break;
399
            }
400
            }
400
            send:
401
            send:
401
            case I2C_SEND_DATA:
402
            case I2C_SEND_DATA:
402
            {
403
            {
403
                if (!i2c_data.slave_sending_data) {
404
                if (!i2c_data_p->slave_sending_data) {
404
                    // If we are not currently sending data, figure out what to reply with
405
                    // If we are not currently sending data, figure out what to reply with
405
                    if (I2C_Process_Send(i2c_data.slave_in_last_byte)) {
406
                    if (I2C_Process_Send(i2c_data_p->slave_in_last_byte)) {
406
                        // Data exists to be returned, send first byte
407
                        // Data exists to be returned, send first byte
407
                        SSPBUF = i2c_data.buffer_out[0];
408
                        SSPBUF = i2c_data_p->buffer_out[0];
408
                        i2c_data.buffer_out_ind = 1;
409
                        i2c_data_p->buffer_out_ind = 1;
409
                        i2c_data.slave_sending_data = 1;
410
                        i2c_data_p->slave_sending_data = 1;
410
                        data_written_to_buffer = 1;
411
                        data_written_to_buffer = 1;
411
                    } else {
412
                    } else {
412
                        // Unknown request
413
                        // Unknown request
413
                        i2c_data.slave_sending_data = 0;
414
                        i2c_data_p->slave_sending_data = 0;
414
                        i2c_data.operating_state = I2C_IDLE;
415
                        i2c_data_p->operating_state = I2C_IDLE;
415
                    }
416
                    }
416
                } else {
417
                } else {
417
                    // Sending remaining data back to master
418
                    // Sending remaining data back to master
418
                    if (i2c_data.buffer_out_ind < i2c_data.buffer_out_len) {
419
                    if (i2c_data_p->buffer_out_ind < i2c_data_p->buffer_out_len) {
419
                        SSPBUF = i2c_data.buffer_out[i2c_data.buffer_out_ind];
420
                        SSPBUF = i2c_data_p->buffer_out[i2c_data_p->buffer_out_ind];
420
                        i2c_data.buffer_out_ind++;
421
                        i2c_data_p->buffer_out_ind++;
421
                        data_written_to_buffer = 1;
422
                        data_written_to_buffer = 1;
422
                    } else {
423
                    } else {
423
                        // Nothing left to send
424
                        // Nothing left to send
424
                        i2c_data.slave_sending_data = 0;
425
                        i2c_data_p->slave_sending_data = 0;
425
                        i2c_data.operating_state = I2C_IDLE;
426
                        i2c_data_p->operating_state = I2C_IDLE;
426
                    }
427
                    }
427
                }
428
                }
428
                break;
429
                break;
429
            }
430
            }
430
            case I2C_RCV_DATA:
431
            case I2C_RCV_DATA:
Line 434... Line 435...
434
                    // Stop bit detected, we need to check to see if we also read data
435
                    // Stop bit detected, we need to check to see if we also read data
435
                    if (data_read_from_buffer) {
436
                    if (data_read_from_buffer) {
436
                        if (SSPSTATbits.D_A == 1) {
437
                        if (SSPSTATbits.D_A == 1) {
437
                            // Data received with stop bit
438
                            // Data received with stop bit
438
                            // TODO: handle i2c buffer overflow
439
                            // TODO: handle i2c buffer overflow
439
                            i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = received_data;
440
                            i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = received_data;
440
                            if (i2c_data.buffer_in_write_ind == MAXI2CBUF-1) {
441
                            if (i2c_data_p->buffer_in_write_ind == MAXI2CBUF-1) {
441
                                i2c_data.buffer_in_write_ind = 0;
442
                                i2c_data_p->buffer_in_write_ind = 0;
442
                            } else {
443
                            } else {
443
                                i2c_data.buffer_in_write_ind++;
444
                                i2c_data_p->buffer_in_write_ind++;
444
                            }
445
                            }
445
                            i2c_data.buffer_in_len_tmp++;
446
                            i2c_data_p->buffer_in_len_tmp++;
446
                            // Save the last byte received
447
                            // Save the last byte received
447
                            i2c_data.slave_in_last_byte = received_data;
448
                            i2c_data_p->slave_in_last_byte = received_data;
448
                            i2c_data.return_status = I2C_DATA_AVAL;
449
                            i2c_data_p->return_status = I2C_DATA_AVAL;
449
                        } else {
450
                        } else {
450
                            DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
451
                            DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
451
                            i2c_data.operating_state = I2C_IDLE;
452
                            i2c_data_p->operating_state = I2C_IDLE;
452
                            i2c_data.return_status = I2C_ERR_NODATA;
453
                            i2c_data_p->return_status = I2C_ERR_NODATA;
453
                        }
454
                        }
454
                    }
455
                    }
455
                    i2c_data.buffer_in_len += i2c_data.buffer_in_len_tmp;
456
                    i2c_data_p->buffer_in_len += i2c_data_p->buffer_in_len_tmp;
456
                    i2c_data.operating_state = I2C_IDLE;
457
                    i2c_data_p->operating_state = I2C_IDLE;
457
                } else if (data_read_from_buffer) {
458
                } else if (data_read_from_buffer) {
458
                    if (SSPSTATbits.D_A == 1) {
459
                    if (SSPSTATbits.D_A == 1) {
459
                        // Data received
460
                        // Data received
460
                        i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = received_data;
461
                        i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = received_data;
461
                        if (i2c_data.buffer_in_write_ind == MAXI2CBUF-1) {
462
                        if (i2c_data_p->buffer_in_write_ind == MAXI2CBUF-1) {
462
                            i2c_data.buffer_in_write_ind = 0;
463
                            i2c_data_p->buffer_in_write_ind = 0;
463
                        } else {
464
                        } else {
464
                            i2c_data.buffer_in_write_ind++;
465
                            i2c_data_p->buffer_in_write_ind++;
465
                        }
466
                        }
466
                        i2c_data.buffer_in_len_tmp++;
467
                        i2c_data_p->buffer_in_len_tmp++;
467
                        // Save the last byte received
468
                        // Save the last byte received
468
                        i2c_data.slave_in_last_byte = received_data;
469
                        i2c_data_p->slave_in_last_byte = received_data;
469
                        i2c_data.return_status = I2C_DATA_AVAL;
470
                        i2c_data_p->return_status = I2C_DATA_AVAL;
470
                    } else {
471
                    } else {
471
                        // Restart bit detected
472
                        // Restart bit detected
472
                        if (SSPSTATbits.R_W == 1) {
473
                        if (SSPSTATbits.R_W == 1) {
473
                            i2c_data.buffer_in_len += i2c_data.buffer_in_len_tmp;
474
                            i2c_data_p->buffer_in_len += i2c_data_p->buffer_in_len_tmp;
474
                            i2c_data.operating_state = I2C_SEND_DATA;
475
                            i2c_data_p->operating_state = I2C_SEND_DATA;
475
                            // Process the first byte immediatly if sending data
476
                            // Process the first byte immediatly if sending data
476
                            goto send;
477
                            goto send;
477
                        } else {
478
                        } else {
478
                            // Bad to recv an address again, we aren't ready
479
                            // Bad to recv an address again, we aren't ready
479
                            DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
480
                            DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
480
                            i2c_data.operating_state = I2C_IDLE;
481
                            i2c_data_p->operating_state = I2C_IDLE;
481
                            i2c_data.return_status = I2C_ERR_NODATA;
482
                            i2c_data_p->return_status = I2C_ERR_NODATA;
482
                        }
483
                        }
483
                    }
484
                    }
484
                }
485
                }
485
                break;
486
                break;
486
            }
487
            }
Line 496... Line 497...
496
    }
497
    }
497
}
498
}
498
 
499
 
499
/* Returns 0 if I2C module is currently busy, otherwise returns status code */
500
/* Returns 0 if I2C module is currently busy, otherwise returns status code */
500
unsigned char I2C_Get_Status() {
501
unsigned char I2C_Get_Status() {
501
    if (i2c_data.operating_mode == I2C_MODE_MASTER) {
502
    if (i2c_data_p->operating_mode == I2C_MODE_MASTER) {
502
        if (i2c_data.master_status != I2C_MASTER_IDLE || i2c_data.buffer_in_len == 0) {
503
        if (i2c_data_p->master_status != I2C_MASTER_IDLE || i2c_data_p->buffer_in_len == 0) {
503
            return 0;
504
            return 0;
504
        } else {
505
        } else {
505
            return i2c_data.return_status;
506
            return i2c_data_p->return_status;
506
        }
507
        }
507
    } else if (i2c_data.operating_mode = I2C_MODE_SLAVE) {
508
    } else if (i2c_data_p->operating_mode = I2C_MODE_SLAVE) {
508
        if (i2c_data.operating_state != I2C_IDLE || i2c_data.buffer_in_len == 0) {
509
        if (i2c_data_p->operating_state != I2C_IDLE || i2c_data_p->buffer_in_len == 0) {
509
            return 0;
510
            return 0;
510
        } else {
511
        } else {
511
            return i2c_data.return_status;
512
            return i2c_data_p->return_status;
512
        }
513
        }
513
    }
514
    }
514
}
515
}
515
 
516
 
516
unsigned char I2C_Buffer_Len() {
517
unsigned char I2C_Buffer_Len() {
517
    return i2c_data.buffer_in_len;
518
    return i2c_data_p->buffer_in_len;
518
}
519
}
519
 
520
 
520
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
521
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
521
unsigned char I2C_Read_Buffer(char *buffer) {
522
unsigned char I2C_Read_Buffer(char *buffer) {
522
    unsigned char i = 0;
523
    unsigned char i = 0;
523
    while (i2c_data.buffer_in_len != 0) {
524
    while (i2c_data_p->buffer_in_len != 0) {
524
        buffer[i] = i2c_data.buffer_in[i2c_data.buffer_in_read_ind];
525
        buffer[i] = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
525
        i++;
526
        i++;
526
        if (i2c_data.buffer_in_read_ind == MAXI2CBUF-1) {
527
        if (i2c_data_p->buffer_in_read_ind == MAXI2CBUF-1) {
527
            i2c_data.buffer_in_read_ind = 0;
528
            i2c_data_p->buffer_in_read_ind = 0;
528
        } else {
529
        } else {
529
            i2c_data.buffer_in_read_ind++;
530
            i2c_data_p->buffer_in_read_ind++;
530
        }
531
        }
531
        i2c_data.buffer_in_len--;
532
        i2c_data_p->buffer_in_len--;
532
    }
533
    }
533
    return i;
534
    return i;
534
}
535
}
535
 
536
 
536
/* Put data to be returned here */
537
/* Put data to be returned here */
537
unsigned char I2C_Process_Send(unsigned char c) {
538
unsigned char I2C_Process_Send(unsigned char c) {
538
    unsigned char ret = 0;
539
    unsigned char ret = 0;
539
    switch (c) {
540
    switch (c) {
540
        case 0xAA:
541
        case 0xAA:
541
            i2c_data.buffer_out[0] = 'A';
542
            i2c_data_p->buffer_out[0] = 'A';
542
            i2c_data.buffer_out_len = 1;
543
            i2c_data_p->buffer_out_len = 1;
543
            ret = 1;
544
            ret = 1;
544
            break;
545
            break;
545
        case 0xBB:
546
        case 0xBB:
546
            i2c_data.buffer_out[0] = '1';
547
            i2c_data_p->buffer_out[0] = '1';
547
            i2c_data.buffer_out[1] = '2';
548
            i2c_data_p->buffer_out[1] = '2';
548
            i2c_data.buffer_out_len = 2;
549
            i2c_data_p->buffer_out_len = 2;
549
            ret = 1;
550
            ret = 1;
550
            break;
551
            break;
551
    }
552
    }
552
    return ret;
553
    return ret;
553
}
554
}
554
555