Subversion Repositories Code-Repo

Rev

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

Rev 234 Rev 235
Line 38... Line 38...
38
 
38
 
39
    INTEnableInterrupts();
39
    INTEnableInterrupts();
40
}
40
}
41
 
41
 
42
// Sends length number of bytes in msg to specified address (no R/W bit)
42
// Sends length number of bytes in msg to specified address (no R/W bit)
-
 
43
// Will return status I2C1_SEND_OK or I2C1_SEND_FAIL
43
void I2C1_Master_Send(uint8_t address, uint8_t *msg, uint32_t length) {
44
void I2C1_Master_Send(uint8_t address, uint8_t *msg, uint32_t length) {
44
    uint32_t i;
45
    uint32_t i;
45
    if (length == 0)
46
    if (length == 0)
46
        return;
47
        return;
47
 
48
 
Line 61... Line 62...
61
    // Generate start condition
62
    // Generate start condition
62
    I2C1CONbits.SEN = 1;
63
    I2C1CONbits.SEN = 1;
63
}
64
}
64
 
65
 
65
// Reads length number of bytes from address (no R/W bit)
66
// Reads length number of bytes from address (no R/W bit)
-
 
67
// Will return status I2C1_RECV_OK or I2C1_RECV_FAIL
66
void I2C1_Master_Recv(uint8_t address, uint32_t length) {
68
void I2C1_Master_Recv(uint8_t address, uint32_t length) {
67
    if (length == 0)
69
    if (length == 0)
68
        return;
70
        return;
69
 
71
 
70
    // Save length and address to get data from
72
    // Save length and address to get data from
Line 80... Line 82...
80
    // Generate start condition
82
    // Generate start condition
81
    I2C1CONbits.SEN = 1;
83
    I2C1CONbits.SEN = 1;
82
}
84
}
83
 
85
 
84
// Writes msg to address then reads length number of bytes from address
86
// Writes msg to address then reads length number of bytes from address
-
 
87
// Will return status I2C1_SEND_FAIL or I2C1_RECV_FAIL or I2C1_RECV_OK
85
void I2C1_Master_Restart(uint8_t address, uint8_t msg, uint32_t length) {
88
void I2C1_Master_Restart(uint8_t address, uint8_t msg, uint32_t length) {
86
    uint8_t c;
89
    uint8_t c;
87
    if (length == 0) {
90
    if (length == 0) {
88
        c = msg;
91
        c = msg;
89
        I2C1_Master_Send(address, &c, 1);
92
        I2C1_Master_Send(address, &c, 1);
Line 135... Line 138...
135
     * 5. During a send ACK or NACK sequence to slave
138
     * 5. During a send ACK or NACK sequence to slave
136
     * 6. Data transfer byte transmitted
139
     * 6. Data transfer byte transmitted
137
     * 7. During a slave-detected stop
140
     * 7. During a slave-detected stop
138
     */
141
     */
139
 
142
 
-
 
143
    if (I2C1STATbits.IWCOL == 1) {
-
 
144
        // TODO: Handle write collisions
-
 
145
        I2C1STATbits.IWCOL = 0;
-
 
146
    }
-
 
147
 
140
    // If we are in the middle of sending data
148
    // If we are in the middle of sending data
141
    if (i2c_data_p->master_status == I2C1_MASTER_SEND) {
149
    if (i2c_data_p->master_status == I2C1_MASTER_SEND) {
142
        switch (i2c_data_p->operating_state) {
150
        switch (i2c_data_p->operating_state) {
143
            case I2C1_IDLE:
151
            case I2C1_IDLE:
144
                break;
152
                break;
Line 154... Line 162...
154
                    if (i2c_data_p->buffer_in_read_ind < i2c_data_p->buffer_in_len) {
162
                    if (i2c_data_p->buffer_in_read_ind < i2c_data_p->buffer_in_len) {
155
                        I2C1TRN = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
163
                        I2C1TRN = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
156
                        i2c_data_p->buffer_in_read_ind++;
164
                        i2c_data_p->buffer_in_read_ind++;
157
                    } else {
165
                    } else {
158
                        // If no more data is to be sent, send stop bit
166
                        // If no more data is to be sent, send stop bit
159
                        i2c_data_p->operating_state = I2C1_IDLE;
167
                        i2c_data_p->operating_state = I2C1_STOPPED;
160
                        I2C1CONbits.PEN = 1;
168
                        I2C1CONbits.PEN = 1;
161
                        i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
162
                        i2c_data_p->return_status = I2C1_SEND_OK;
169
                        i2c_data_p->return_status = I2C1_SEND_OK;
163
                    }
170
                    }
164
                } else {
171
                } else {
165
                    // If a NACK is received, stop transmission and send error
172
                    // If a NACK is received, stop transmission and send error
166
                    i2c_data_p->operating_state = I2C1_IDLE;
173
                    i2c_data_p->operating_state = I2C1_STOPPED;
167
                    I2C1CONbits.PEN = 1;
174
                    I2C1CONbits.PEN = 1;
168
                    i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
169
                    i2c_data_p->return_status = I2C1_SEND_FAIL;
175
                    i2c_data_p->return_status = I2C1_SEND_FAIL;
170
                }
176
                }
171
                break;
177
                break;
-
 
178
            case I2C1_STOPPED:
-
 
179
                i2c_data_p->operating_state = I2C1_IDLE;
-
 
180
                i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
181
                break;
172
        }
182
        }
173
    // If we are in the middle of receiving data
183
    // If we are in the middle of receiving data
174
    } else if (i2c_data_p->master_status == I2C1_MASTER_RECV) {
184
    } else if (i2c_data_p->master_status == I2C1_MASTER_RECV) {
175
        switch (i2c_data_p->operating_state) {
185
        switch (i2c_data_p->operating_state) {
176
            case I2C1_IDLE:
186
            case I2C1_IDLE:
Line 186... Line 196...
186
                    // If an ACK is received, set module to receive 1 byte of data
196
                    // If an ACK is received, set module to receive 1 byte of data
187
                    i2c_data_p->operating_state = I2C1_RCV_DATA;
197
                    i2c_data_p->operating_state = I2C1_RCV_DATA;
188
                    I2C1CONbits.RCEN = 1;
198
                    I2C1CONbits.RCEN = 1;
189
                } else {
199
                } else {
190
                    // If a NACK is received, stop transmission and send error
200
                    // If a NACK is received, stop transmission and send error
191
                    i2c_data_p->operating_state = I2C1_IDLE;
201
                    i2c_data_p->operating_state = I2C1_STOPPED;
192
                    I2C1CONbits.PEN = 1;
202
                    I2C1CONbits.PEN = 1;
193
                    i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
194
                    i2c_data_p->return_status = I2C1_RECV_FAIL;
203
                    i2c_data_p->return_status = I2C1_RECV_FAIL;
195
                }
204
                }
196
                break;
205
                break;
197
            case I2C1_RCV_DATA:
206
            case I2C1_RCV_DATA:
198
                // On receive, save byte into buffer
207
                // On receive, save byte into buffer
199
                // TODO: Handle I2C buffer overflow
208
                // TODO: Handle possible I2C buffer overflow
200
                i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = I2C1RCV;
209
                i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = I2C1RCV;
201
                i2c_data_p->buffer_in_write_ind++;
210
                i2c_data_p->buffer_in_write_ind++;
202
                if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
211
                if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
203
                    // If we still need to read, send an ACK to the slave
212
                    // If we still need to read, send an ACK to the slave
204
                    i2c_data_p->operating_state = I2C1_REQ_DATA;
213
                    i2c_data_p->operating_state = I2C1_REQ_DATA;
Line 215... Line 224...
215
                // Set module to receive one byte of data
224
                // Set module to receive one byte of data
216
                i2c_data_p->operating_state = I2C1_RCV_DATA;
225
                i2c_data_p->operating_state = I2C1_RCV_DATA;
217
                I2C1CONbits.RCEN = 1;
226
                I2C1CONbits.RCEN = 1;
218
                break;
227
                break;
219
            case I2C1_SEND_STOP:
228
            case I2C1_SEND_STOP:
220
                // Send the stop bit and copy message to send to Main()
229
                // Send the stop bit
221
                i2c_data_p->operating_state = I2C1_IDLE;
230
                i2c_data_p->operating_state = I2C1_STOPPED;
222
                I2C1CONbits.PEN = 1;
231
                I2C1CONbits.PEN = 1;
223
                i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
224
                i2c_data_p->return_status = I2C1_RECV_OK;
232
                i2c_data_p->return_status = I2C1_RECV_OK;
225
                break;
233
                break;
-
 
234
            case I2C1_STOPPED:
-
 
235
                i2c_data_p->operating_state = I2C1_IDLE;
-
 
236
                i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
237
                break;
226
        }
238
        }
227
    } else if (i2c_data_p->master_status == I2C1_MASTER_RESTART) {
239
    } else if (i2c_data_p->master_status == I2C1_MASTER_RESTART) {
228
        switch (i2c_data_p->operating_state) {
240
        switch (i2c_data_p->operating_state) {
229
            case I2C1_IDLE:
241
            case I2C1_IDLE:
230
                break;
242
                break;
Line 239... Line 251...
239
                    // If an ACK is received, send first byte of data
251
                    // If an ACK is received, send first byte of data
240
                    I2C1TRN = i2c_data_p->buffer_in[0];
252
                    I2C1TRN = i2c_data_p->buffer_in[0];
241
                    i2c_data_p->operating_state = I2C1_CHECK_ACK_RESTART;
253
                    i2c_data_p->operating_state = I2C1_CHECK_ACK_RESTART;
242
                } else {
254
                } else {
243
                    // If a NACK is received, stop transmission and send error
255
                    // If a NACK is received, stop transmission and send error
244
                    i2c_data_p->operating_state = I2C1_IDLE;
256
                    i2c_data_p->operating_state = I2C1_STOPPED;
245
                    I2C1CONbits.PEN = 1;
257
                    I2C1CONbits.PEN = 1;
246
                    i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
247
                    i2c_data_p->return_status = I2C1_SEND_FAIL;
258
                    i2c_data_p->return_status = I2C1_SEND_FAIL;
248
                }
259
                }
249
                break;
260
                break;
250
            case I2C1_CHECK_ACK_RESTART:
261
            case I2C1_CHECK_ACK_RESTART:
251
                if (!I2C1STATbits.ACKSTAT) {
262
                if (!I2C1STATbits.ACKSTAT) {
252
                    I2C1CONbits.RSEN = 1;
263
                    I2C1CONbits.RSEN = 1;
253
                    i2c_data_p->operating_state = I2C1_SEND_ADDR_2;
264
                    i2c_data_p->operating_state = I2C1_SEND_ADDR_2;
254
                } else {
265
                } else {
255
                    // If a NACK is received, stop transmission and send error
266
                    // If a NACK is received, stop transmission and send error
256
                    i2c_data_p->operating_state = I2C1_IDLE;
267
                    i2c_data_p->operating_state = I2C1_STOPPED;
257
                    I2C1CONbits.PEN = 1;
268
                    I2C1CONbits.PEN = 1;
258
                    i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
259
                    i2c_data_p->return_status = I2C1_SEND_FAIL;
269
                    i2c_data_p->return_status = I2C1_SEND_FAIL;
260
                }
270
                }
261
                break;
271
                break;
262
            case I2C1_SEND_ADDR_2:
272
            case I2C1_SEND_ADDR_2:
263
                // Send the address with read bit set
273
                // Send the address with read bit set
Line 270... Line 280...
270
                    // If an ACK is received, set module to receive 1 byte of data
280
                    // If an ACK is received, set module to receive 1 byte of data
271
                    i2c_data_p->operating_state = I2C1_RCV_DATA;
281
                    i2c_data_p->operating_state = I2C1_RCV_DATA;
272
                    I2C1CONbits.RCEN = 1;
282
                    I2C1CONbits.RCEN = 1;
273
                } else {
283
                } else {
274
                    // If a NACK is received, stop transmission and send error
284
                    // If a NACK is received, stop transmission and send error
275
                    i2c_data_p->operating_state = I2C1_IDLE;
285
                    i2c_data_p->operating_state = I2C1_STOPPED;
276
                    I2C1CONbits.PEN = 1;
286
                    I2C1CONbits.PEN = 1;
277
                    i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
278
                    i2c_data_p->return_status = I2C1_RECV_FAIL;
287
                    i2c_data_p->return_status = I2C1_RECV_FAIL;
279
                }
288
                }
280
                break;
289
                break;
281
            case I2C1_RCV_DATA:
290
            case I2C1_RCV_DATA:
282
                // On receive, save byte into buffer
291
                // On receive, save byte into buffer
283
                // TODO: Handle I2C buffer overflow
292
                // TODO: Handle possible I2C buffer overflow
284
                i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = I2C1RCV;
293
                i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = I2C1RCV;
285
                i2c_data_p->buffer_in_write_ind++;
294
                i2c_data_p->buffer_in_write_ind++;
286
                if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
295
                if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
287
                    // If we still need to read, send an ACK to the slave
296
                    // If we still need to read, send an ACK to the slave
288
                    i2c_data_p->operating_state = I2C1_REQ_DATA;
297
                    i2c_data_p->operating_state = I2C1_REQ_DATA;
Line 299... Line 308...
299
                // Set module to receive one byte of data
308
                // Set module to receive one byte of data
300
                i2c_data_p->operating_state = I2C1_RCV_DATA;
309
                i2c_data_p->operating_state = I2C1_RCV_DATA;
301
                I2C1CONbits.RCEN = 1;
310
                I2C1CONbits.RCEN = 1;
302
                break;
311
                break;
303
            case I2C1_SEND_STOP:
312
            case I2C1_SEND_STOP:
304
                // Send the stop bit and copy message to send to Main()
313
                // Send the stop bit
305
                i2c_data_p->operating_state = I2C1_IDLE;
314
                i2c_data_p->operating_state = I2C1_STOPPED;
306
                I2C1CONbits.PEN = 1;
315
                I2C1CONbits.PEN = 1;
307
                i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
308
                i2c_data_p->return_status = I2C1_RECV_OK;
316
                i2c_data_p->return_status = I2C1_RECV_OK;
309
                break;
317
                break;
-
 
318
            case I2C1_STOPPED:
-
 
319
                i2c_data_p->operating_state = I2C1_IDLE;
-
 
320
                i2c_data_p->master_status = I2C1_MASTER_IDLE;
-
 
321
                break;
310
        }
322
        }
311
    }
323
    }
312
}
324
}
313
 
325
 
314
void I2C1_Interrupt_Slave() {
326
void I2C1_Interrupt_Slave() {
Line 397... Line 409...
397
    }
409
    }
398
}
410
}
399
 
411
 
400
/* Returns 0 if I2C module is currently busy, otherwise returns status code */
412
/* Returns 0 if I2C module is currently busy, otherwise returns status code */
401
uint8_t I2C1_Get_Status() {
413
uint8_t I2C1_Get_Status() {
402
        if (i2c_data_p->master_status != I2C1_MASTER_IDLE ||
414
        if (i2c_data_p->master_status == I2C1_MASTER_IDLE &&
403
                i2c_data_p->buffer_in_len == 0) {
415
                i2c_data_p->operating_state == I2C1_IDLE &&
404
            return 0;
416
                I2C1STATbits.TBF == 0) {
405
        } else {
-
 
406
            return i2c_data_p->return_status;
417
            return i2c_data_p->return_status;
-
 
418
        } else {
-
 
419
            return 0;
407
        }
420
        }
408
}
421
}
409
 
422
 
410
uint8_t I2C1_Buffer_Len() {
423
uint8_t I2C1_Buffer_Len() {
411
    return i2c_data_p->buffer_in_len;
424
    return i2c_data_p->buffer_in_len;