Subversion Repositories Code-Repo

Rev

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

Rev 120 Rev 121
Line 27... Line 27...
27
    // Enable I2C interrupt
27
    // Enable I2C interrupt
28
    PIE1bits.SSPIE = 1;
28
    PIE1bits.SSPIE = 1;
29
}
29
}
30
 
30
 
31
// Setup the PIC to operate as a master.
31
// Setup the PIC to operate as a master.
32
void I2C_Configure_Master() {
32
void I2C_Configure_Master(unsigned char speed) {
33
    i2c_data.operating_mode = I2C_MODE_MASTER;
33
    i2c_data.operating_mode = I2C_MODE_MASTER;
34
 
34
 
35
    TRISCbits.TRISC3 = 1;
35
    TRISCbits.TRISC3 = 1;
36
    TRISCbits.TRISC4 = 1;
36
    TRISCbits.TRISC4 = 1;
37
 
37
 
38
    SSPSTAT = 0x0;
38
    SSPSTAT = 0x0;
39
    SSPCON1 = 0x0;
39
    SSPCON1 = 0x0;
40
    SSPCON2 = 0x0;
40
    SSPCON2 = 0x0;
41
    SSPCON1bits.SSPM = 0x8; // I2C Master Mode
41
    SSPCON1bits.SSPM = 0x8; // I2C Master Mode
-
 
42
    if (speed) {
42
    SSPADD = 0x77;          // Operate at 100KHz (48MHz)
43
        SSPADD = 0x74;          // Operate at 100KHz (48MHz)
-
 
44
    } else {
-
 
45
        SSPADD = 0x1A;          // Operate at 400KHz (48MHz)
-
 
46
    }
43
    SSPSTATbits.SMP = 1;    // Disable Slew Rate Control
47
    SSPSTATbits.SMP = 1;    // Disable Slew Rate Control
44
    SSPCON1bits.SSPEN = 1;  // Enable MSSP Module
48
    SSPCON1bits.SSPEN = 1;  // Enable MSSP Module
45
}
49
}
46
 
50
 
47
// Sends length number of bytes in msg to specified address (no R/W bit)
51
// Sends length number of bytes in msg to specified address (no R/W bit)
Line 55... Line 59...
55
        i2c_data.buffer_in[i] = msg[i];
59
        i2c_data.buffer_in[i] = msg[i];
56
    }
60
    }
57
    i2c_data.buffer_in_len = length;
61
    i2c_data.buffer_in_len = length;
58
    i2c_data.master_dest_addr = address;
62
    i2c_data.master_dest_addr = address;
59
    i2c_data.buffer_in_read_ind = 0;
63
    i2c_data.buffer_in_read_ind = 0;
-
 
64
    i2c_data.buffer_in_write_ind = 0;
60
 
65
 
61
    // Change status to 'next' operation
66
    // Change status to 'next' operation
62
    i2c_data.operating_state = I2C_SEND_ADDR;
67
    i2c_data.operating_state = I2C_SEND_ADDR;
63
    i2c_data.master_status = I2C_MASTER_SEND;
68
    i2c_data.master_status = I2C_MASTER_SEND;
64
    
69
    
Line 73... Line 78...
73
 
78
 
74
    // Save length and address to get data from
79
    // Save length and address to get data from
75
    i2c_data.buffer_in_len = length;
80
    i2c_data.buffer_in_len = length;
76
    i2c_data.master_dest_addr = address;
81
    i2c_data.master_dest_addr = address;
77
    i2c_data.buffer_in_read_ind = 0;
82
    i2c_data.buffer_in_read_ind = 0;
-
 
83
    i2c_data.buffer_in_write_ind = 0;
78
 
84
 
79
    // Change status to 'next' operation
85
    // Change status to 'next' operation
80
    i2c_data.operating_state = I2C_SEND_ADDR;
86
    i2c_data.operating_state = I2C_SEND_ADDR;
81
    i2c_data.master_status = I2C_MASTER_RECV;
87
    i2c_data.master_status = I2C_MASTER_RECV;
82
    
88
    
Line 96... Line 102...
96
    // Save length and address to get data from
102
    // Save length and address to get data from
97
    i2c_data.buffer_in[0] = msg;
103
    i2c_data.buffer_in[0] = msg;
98
    i2c_data.buffer_in_len = length;
104
    i2c_data.buffer_in_len = length;
99
    i2c_data.master_dest_addr = address;
105
    i2c_data.master_dest_addr = address;
100
    i2c_data.buffer_in_read_ind = 0;
106
    i2c_data.buffer_in_read_ind = 0;
-
 
107
    i2c_data.buffer_in_write_ind = 0;
101
 
108
 
102
    // Change status to 'next' operation
109
    // Change status to 'next' operation
103
    i2c_data.operating_state = I2C_SEND_ADDR;
110
    i2c_data.operating_state = I2C_SEND_ADDR;
104
    i2c_data.master_status = I2C_MASTER_RESTART;
111
    i2c_data.master_status = I2C_MASTER_RESTART;
105
 
112
 
Line 194... Line 201...
194
                    i2c_data.return_status = I2C_RECV_FAIL;
201
                    i2c_data.return_status = I2C_RECV_FAIL;
195
                }
202
                }
196
                break;
203
                break;
197
            case I2C_RCV_DATA:
204
            case I2C_RCV_DATA:
198
                // On receive, save byte into buffer
205
                // On receive, save byte into buffer
-
 
206
                // TODO: handle i2c buffer overflow
199
                i2c_data.buffer_in[i2c_data.buffer_in_read_ind] = SSPBUF;
207
                i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = SSPBUF;
200
                i2c_data.buffer_in_read_ind++;
208
                i2c_data.buffer_in_write_ind++;
201
                if (i2c_data.buffer_in_read_ind < i2c_data.buffer_in_len) {
209
                if (i2c_data.buffer_in_write_ind < i2c_data.buffer_in_len) {
202
                    // If we still need to read, send an ACK to the slave
210
                    // If we still need to read, send an ACK to the slave
203
                    i2c_data.operating_state = I2C_REQ_DATA;
211
                    i2c_data.operating_state = I2C_REQ_DATA;
204
                    SSPCON2bits.ACKDT = 0;  // ACK
212
                    SSPCON2bits.ACKDT = 0;  // ACK
205
                    SSPCON2bits.ACKEN = 1;
213
                    SSPCON2bits.ACKEN = 1;
206
                } else {
214
                } else {
Line 277... Line 285...
277
                    i2c_data.return_status = I2C_RECV_FAIL;
285
                    i2c_data.return_status = I2C_RECV_FAIL;
278
                }
286
                }
279
                break;
287
                break;
280
            case I2C_RCV_DATA:
288
            case I2C_RCV_DATA:
281
                // On receive, save byte into buffer
289
                // On receive, save byte into buffer
-
 
290
                // TODO: handle i2c buffer overflow
282
                i2c_data.buffer_in[i2c_data.buffer_in_read_ind] = SSPBUF;
291
                i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = SSPBUF;
283
                i2c_data.buffer_in_read_ind++;
292
                i2c_data.buffer_in_write_ind++;
284
                if (i2c_data.buffer_in_read_ind < i2c_data.buffer_in_len) {
293
                if (i2c_data.buffer_in_write_ind < i2c_data.buffer_in_len) {
285
                    // If we still need to read, send an ACK to the slave
294
                    // If we still need to read, send an ACK to the slave
286
                    i2c_data.operating_state = I2C_REQ_DATA;
295
                    i2c_data.operating_state = I2C_REQ_DATA;
287
                    SSPCON2bits.ACKDT = 0;  // ACK
296
                    SSPCON2bits.ACKDT = 0;  // ACK
288
                    SSPCON2bits.ACKEN = 1;
297
                    SSPCON2bits.ACKEN = 1;
289
                } else {
298
                } else {
Line 315... Line 324...
315
    unsigned char data_written_to_buffer = 0;
324
    unsigned char data_written_to_buffer = 0;
316
    unsigned char overrun_error = 0;
325
    unsigned char overrun_error = 0;
317
 
326
 
318
    // Clear SSPOV (overflow bit)
327
    // Clear SSPOV (overflow bit)
319
    if (SSPCON1bits.SSPOV == 1) {
328
    if (SSPCON1bits.SSPOV == 1) {
320
//        DBG_PRINT_I2C("I2C: overflow detected\r\n");
329
        DBG_PRINT_I2C("I2C: overflow detected\r\n");
321
        SSPCON1bits.SSPOV = 0;
330
        SSPCON1bits.SSPOV = 0;
322
        // We failed to read the buffer in time, so we know we
331
        // We failed to read the buffer in time, so we know we
323
        //  can't properly receive this message, just put us in the
332
        //  can't properly receive this message, just put us in the
324
        //  a state where we are looking for a new message
333
        //  a state where we are looking for a new message
325
        i2c_data.operating_state = I2C_IDLE;
334
        i2c_data.operating_state = I2C_IDLE;
Line 328... Line 337...
328
    }
337
    }
329
 
338
 
330
    // Read SPPxBUF if it is full
339
    // Read SPPxBUF if it is full
331
    if (SSPSTATbits.BF == 1) {
340
    if (SSPSTATbits.BF == 1) {
332
        received_data = SSPBUF;
341
        received_data = SSPBUF;
333
//        DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF);
342
        DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF);
334
        data_read_from_buffer = 1;
343
        data_read_from_buffer = 1;
335
    }
344
    }
336
 
345
 
337
    if (!overrun_error) {
346
    if (!overrun_error) {
338
        switch (i2c_data.operating_state) {
347
        switch (i2c_data.operating_state) {
Line 342... Line 351...
342
                if (SSPSTATbits.S == 1) {
351
                if (SSPSTATbits.S == 1) {
343
                    i2c_data.buffer_in_len_tmp = 0;
352
                    i2c_data.buffer_in_len_tmp = 0;
344
                    i2c_data.operating_state = I2C_STARTED;
353
                    i2c_data.operating_state = I2C_STARTED;
345
//                    if (data_read_from_buffer) {
354
//                    if (data_read_from_buffer) {
346
//                        if (SSPSTATbits.D_A == 1) {
355
//                        if (SSPSTATbits.D_A == 1) {
347
////                            DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n");
356
//                            DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n");
348
//                            // This is bad because we got data and we wanted an address
357
//                            // This is bad because we got data and we wanted an address
349
//                            i2c_data.operating_state = I2C_IDLE;
358
//                            i2c_data.operating_state = I2C_IDLE;
350
//                            i2c_data.return_status = I2C_ERR_NOADDR;
359
//                            i2c_data.return_status = I2C_ERR_NOADDR;
351
//                        } else {
360
//                        } else {
352
//                            // Determine if we are sending or receiving data
361
//                            // Determine if we are sending or receiving data
Line 379... Line 388...
379
                            i2c_data.operating_state = I2C_SEND_DATA;
388
                            i2c_data.operating_state = I2C_SEND_DATA;
380
                            // Process the first byte immediatly if sending data
389
                            // Process the first byte immediatly if sending data
381
                            goto send;
390
                            goto send;
382
                        }
391
                        }
383
                    } else {
392
                    } else {
384
//                        DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
393
                        DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
385
                        i2c_data.operating_state = I2C_IDLE;
394
                        i2c_data.operating_state = I2C_IDLE;
386
                        i2c_data.return_status = I2C_ERR_NODATA;
395
                        i2c_data.return_status = I2C_ERR_NODATA;
387
                    }
396
                    }
388
                }
397
                }
389
                break;
398
                break;
Line 424... Line 433...
424
                if (SSPSTATbits.P == 1) {
433
                if (SSPSTATbits.P == 1) {
425
                    // Stop bit detected, we need to check to see if we also read data
434
                    // Stop bit detected, we need to check to see if we also read data
426
                    if (data_read_from_buffer) {
435
                    if (data_read_from_buffer) {
427
                        if (SSPSTATbits.D_A == 1) {
436
                        if (SSPSTATbits.D_A == 1) {
428
                            // Data received with stop bit
437
                            // Data received with stop bit
-
 
438
                            // TODO: handle i2c buffer overflow
429
                            i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = received_data;
439
                            i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = received_data;
430
                            if (i2c_data.buffer_in_write_ind == MAXI2CBUF-1) {
440
                            if (i2c_data.buffer_in_write_ind == MAXI2CBUF-1) {
431
                                i2c_data.buffer_in_write_ind = 0;
441
                                i2c_data.buffer_in_write_ind = 0;
432
                            } else {
442
                            } else {
433
                                i2c_data.buffer_in_write_ind++;
443
                                i2c_data.buffer_in_write_ind++;
Line 435... Line 445...
435
                            i2c_data.buffer_in_len_tmp++;
445
                            i2c_data.buffer_in_len_tmp++;
436
                            // Save the last byte received
446
                            // Save the last byte received
437
                            i2c_data.slave_in_last_byte = received_data;
447
                            i2c_data.slave_in_last_byte = received_data;
438
                            i2c_data.return_status = I2C_DATA_AVAL;
448
                            i2c_data.return_status = I2C_DATA_AVAL;
439
                        } else {
449
                        } else {
440
//                            DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
450
                            DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
441
                            i2c_data.operating_state = I2C_IDLE;
451
                            i2c_data.operating_state = I2C_IDLE;
442
                            i2c_data.return_status = I2C_ERR_NODATA;
452
                            i2c_data.return_status = I2C_ERR_NODATA;
443
                        }
453
                        }
444
                    }
454
                    }
445
                    i2c_data.buffer_in_len += i2c_data.buffer_in_len_tmp;
455
                    i2c_data.buffer_in_len += i2c_data.buffer_in_len_tmp;
Line 464... Line 474...
464
                            i2c_data.operating_state = I2C_SEND_DATA;
474
                            i2c_data.operating_state = I2C_SEND_DATA;
465
                            // Process the first byte immediatly if sending data
475
                            // Process the first byte immediatly if sending data
466
                            goto send;
476
                            goto send;
467
                        } else {
477
                        } else {
468
                            // Bad to recv an address again, we aren't ready
478
                            // Bad to recv an address again, we aren't ready
469
//                            DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
479
                            DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
470
                            i2c_data.operating_state = I2C_IDLE;
480
                            i2c_data.operating_state = I2C_IDLE;
471
                            i2c_data.return_status = I2C_ERR_NODATA;
481
                            i2c_data.return_status = I2C_ERR_NODATA;
472
                        }
482
                        }
473
                    }
483
                    }
474
                }
484
                }
Line 501... Line 511...
501
            return i2c_data.return_status;
511
            return i2c_data.return_status;
502
        }
512
        }
503
    }
513
    }
504
}
514
}
505
 
515
 
-
 
516
unsigned char I2C_Buffer_Len() {
-
 
517
    return i2c_data.buffer_in_len;
-
 
518
}
-
 
519
 
506
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
520
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
507
unsigned char I2C_Read_Buffer(char *buffer) {
521
unsigned char I2C_Read_Buffer(char *buffer) {
508
    unsigned char i = 0;
522
    unsigned char i = 0;
509
    while (i2c_data.buffer_in_len != 0) {
523
    while (i2c_data.buffer_in_len != 0) {
510
        buffer[i] = i2c_data.buffer_in[i2c_data.buffer_in_read_ind];
524
        buffer[i] = i2c_data.buffer_in[i2c_data.buffer_in_read_ind];