Subversion Repositories Code-Repo

Rev

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

Rev 228 Rev 232
Line 1... Line -...
1
#include <xc.h>
-
 
2
#include "defines.h"
1
#include "defines.h"
3
#include "base_I2C.h"
2
#include "base_I2C.h"
4
 
3
 
5
static I2C_DATA *i2c_data_p;
4
static I2C_DATA *i2c_data_p;
6
 
5
 
Line 30... Line 29...
30
    // Enable I2C interrupt
29
    // Enable I2C interrupt
31
    PIE1bits.SSP1IE = 1;
30
    PIE1bits.SSP1IE = 1;
32
}
31
}
33
 
32
 
34
// Setup the PIC to operate as a master.
33
// Setup the PIC to operate as a master.
35
void I2C_Configure_Master(char speed) {
34
void I2C_Configure_Master(uint8_t speed) {
36
    i2c_data_p->operating_mode = I2C_MODE_MASTER;
35
    i2c_data_p->operating_mode = I2C_MODE_MASTER;
37
 
36
 
38
    I2C_CLK_TRIS = 1;
37
    I2C_CLK_TRIS = 1;
39
    I2C_DAT_TRIS = 1;
38
    I2C_DAT_TRIS = 1;
40
 
39
 
Line 50... Line 49...
50
    SSPSTATbits.SMP = 1;    // Disable Slew Rate Control
49
    SSPSTATbits.SMP = 1;    // Disable Slew Rate Control
51
    SSPCON1bits.SSPEN = 1;  // Enable MSSP Module
50
    SSPCON1bits.SSPEN = 1;  // Enable MSSP Module
52
}
51
}
53
 
52
 
54
// Sends length number of bytes in msg to specified address (no R/W bit)
53
// Sends length number of bytes in msg to specified address (no R/W bit)
55
void I2C_Master_Send(char address, char length, char *msg) {
54
void I2C_Master_Send(uint8_t address, uint8_t length, uint8_t *msg) {
56
    char i;
55
    uint8_t i;
57
    if (length == 0)
56
    if (length == 0)
58
        return;
57
        return;
59
    
58
    
60
    // Copy message to send into buffer and save length/address
59
    // Copy message to send into buffer and save length/address
61
    for (i = 0; i < length; i++) {
60
    for (i = 0; i < length; i++) {
Line 73... Line 72...
73
    // Generate start condition
72
    // Generate start condition
74
    SSPCON2bits.SEN = 1;
73
    SSPCON2bits.SEN = 1;
75
}
74
}
76
 
75
 
77
// Reads length number of bytes from address (no R/W bit)
76
// Reads length number of bytes from address (no R/W bit)
78
void I2C_Master_Recv(char address, char length) {
77
void I2C_Master_Recv(uint8_t address, uint8_t length) {
79
    if (length == 0)
78
    if (length == 0)
80
        return;
79
        return;
81
 
80
 
82
    // Save length and address to get data from
81
    // Save length and address to get data from
83
    i2c_data_p->buffer_in_len = length;
82
    i2c_data_p->buffer_in_len = length;
Line 92... Line 91...
92
    // Generate start condition
91
    // Generate start condition
93
    SSPCON2bits.SEN = 1;
92
    SSPCON2bits.SEN = 1;
94
}
93
}
95
 
94
 
96
// Writes msg to address then reads length number of bytes from address
95
// Writes msg to address then reads length number of bytes from address
97
void I2C_Master_Restart(char address, char msg, char length) {
96
void I2C_Master_Restart(uint8_t address, uint8_t msg, uint8_t length) {
98
    char c;
97
    uint8_t c;
99
    if (length == 0) {
98
    if (length == 0) {
100
        c = msg;
99
        c = msg;
101
        I2C_Master_Send(address, 1, &c);
100
        I2C_Master_Send(address, 1, &c);
102
        return;
101
        return;
103
    }
102
    }
Line 116... Line 115...
116
    // Generate start condition
115
    // Generate start condition
117
    SSPCON2bits.SEN = 1;
116
    SSPCON2bits.SEN = 1;
118
}
117
}
119
 
118
 
120
// Setup the PIC to operate as a slave. The address must not include the R/W bit
119
// Setup the PIC to operate as a slave. The address must not include the R/W bit
121
void I2C_Configure_Slave(char addr) {
120
void I2C_Configure_Slave(uint8_t addr) {
122
    i2c_data_p->operating_mode = I2C_MODE_SLAVE;
121
    i2c_data_p->operating_mode = I2C_MODE_SLAVE;
123
 
122
 
124
    // Ensure the two lines are set for input (we are a slave)
123
    // Ensure the two lines are set for input (we are a slave)
125
    I2C_CLK_TRIS = 1;
124
    I2C_CLK_TRIS = 1;
126
    I2C_DAT_TRIS = 1;
125
    I2C_DAT_TRIS = 1;
Line 320... Line 319...
320
        }
319
        }
321
    }
320
    }
322
}
321
}
323
 
322
 
324
void I2C_Interrupt_Slave() {
323
void I2C_Interrupt_Slave() {
325
    char received_data;
324
    uint8_t received_data;
326
    char data_read_from_buffer = 0;
325
    uint8_t data_read_from_buffer = 0;
327
    char data_written_to_buffer = 0;
326
    uint8_t data_written_to_buffer = 0;
328
    char overrun_error = 0;
327
    uint8_t overrun_error = 0;
329
 
328
 
330
    // Clear SSPOV (overflow bit)
329
    // Clear SSPOV (overflow bit)
331
    if (SSPCON1bits.SSPOV == 1) {
330
    if (SSPCON1bits.SSPOV == 1) {
332
        SSPCON1bits.SSPOV = 0;
331
        SSPCON1bits.SSPOV = 0;
333
        // 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
Line 351... Line 350...
351
            {
350
            {
352
                // Ignore anything except a start
351
                // Ignore anything except a start
353
                if (SSPSTATbits.S == 1) {
352
                if (SSPSTATbits.S == 1) {
354
                    i2c_data_p->buffer_in_len_tmp = 0;
353
                    i2c_data_p->buffer_in_len_tmp = 0;
355
                    i2c_data_p->operating_state = I2C_STARTED;
354
                    i2c_data_p->operating_state = I2C_STARTED;
356
//                    if (data_read_from_buffer) {
-
 
357
//                        if (SSPSTATbits.D_A == 1) {
-
 
358
//                            DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n");
-
 
359
//                            // This is bad because we got data and we wanted an address
-
 
360
//                            i2c_data_p->operating_state = I2C_IDLE;
-
 
361
//                            i2c_data_p->return_status = I2C_ERR_NOADDR;
-
 
362
//                        } else {
-
 
363
//                            // Determine if we are sending or receiving data
-
 
364
//                            if (SSPSTATbits.R_W == 1) {
-
 
365
//                                i2c_data_p->operating_state = I2C_SEND_DATA;
-
 
366
//                            } else {
-
 
367
//                                i2c_data_p->operating_state = I2C_RCV_DATA;
-
 
368
//                            }
-
 
369
//                        }
-
 
370
//                    } else {
-
 
371
//                        i2c_data_p->operating_state = I2C_STARTED;
-
 
372
//                    }
-
 
373
                }
355
                }
374
                break;
356
                break;
375
            }
357
            }
376
            case I2C_STARTED:
358
            case I2C_STARTED:
377
            {
359
            {
Line 401... Line 383...
401
            send:
383
            send:
402
            case I2C_SEND_DATA:
384
            case I2C_SEND_DATA:
403
            {
385
            {
404
                if (!i2c_data_p->slave_sending_data) {
386
                if (!i2c_data_p->slave_sending_data) {
405
                    // If we are not currently sending data, figure out what to reply with
387
                    // If we are not currently sending data, figure out what to reply with
406
                    if (I2C_Process_Send(i2c_data_p->slave_in_last_byte)) {
388
                    if (I2C_Process_Receive(i2c_data_p->slave_in_last_byte)) {
407
                        // Data exists to be returned, send first byte
389
                        // Data exists to be returned, send first byte
408
                        SSPBUF = i2c_data_p->buffer_out[0];
390
                        SSPBUF = i2c_data_p->buffer_out[0];
409
                        i2c_data_p->buffer_out_ind = 1;
391
                        i2c_data_p->buffer_out_ind = 1;
410
                        i2c_data_p->slave_sending_data = 1;
392
                        i2c_data_p->slave_sending_data = 1;
411
                        data_written_to_buffer = 1;
393
                        data_written_to_buffer = 1;
Line 494... Line 476...
494
        }
476
        }
495
    }
477
    }
496
}
478
}
497
 
479
 
498
/* Returns 0 if I2C module is currently busy, otherwise returns status code */
480
/* Returns 0 if I2C module is currently busy, otherwise returns status code */
499
char I2C_Get_Status() {
481
uint8_t I2C_Get_Status() {
500
    if (i2c_data_p->operating_mode == I2C_MODE_MASTER) {
482
    if (i2c_data_p->operating_mode == I2C_MODE_MASTER) {
501
        if (i2c_data_p->master_status != I2C_MASTER_IDLE || i2c_data_p->buffer_in_len == 0) {
483
        if (i2c_data_p->master_status != I2C_MASTER_IDLE || i2c_data_p->buffer_in_len == 0) {
502
            return 0;
484
            return 0;
503
        } else {
485
        } else {
504
            return i2c_data_p->return_status;
486
            return i2c_data_p->return_status;
Line 510... Line 492...
510
            return i2c_data_p->return_status;
492
            return i2c_data_p->return_status;
511
        }
493
        }
512
    }
494
    }
513
}
495
}
514
 
496
 
515
char I2C_Buffer_Len() {
497
uint8_t I2C_Buffer_Len() {
516
    return i2c_data_p->buffer_in_len;
498
    return i2c_data_p->buffer_in_len;
517
}
499
}
518
 
500
 
519
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
501
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
520
char I2C_Read_Buffer(char *buffer) {
502
uint8_t I2C_Read_Buffer(uint8_t *buffer) {
521
    char i = 0;
503
    uint8_t i = 0;
522
    while (i2c_data_p->buffer_in_len != 0) {
504
    while (i2c_data_p->buffer_in_len != 0) {
523
        buffer[i] = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
505
        buffer[i] = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
524
        i++;
506
        i++;
525
        if (i2c_data_p->buffer_in_read_ind == MAXI2CBUF-1) {
507
        if (i2c_data_p->buffer_in_read_ind == MAXI2CBUF-1) {
526
            i2c_data_p->buffer_in_read_ind = 0;
508
            i2c_data_p->buffer_in_read_ind = 0;
Line 531... Line 513...
531
    }
513
    }
532
    return i;
514
    return i;
533
}
515
}
534
 
516
 
535
/* Put data to be returned here */
517
/* Put data to be returned here */
536
char I2C_Process_Send(char c) {
518
uint8_t I2C_Process_Receive(uint8_t c) {
537
    char ret = 0;
519
    uint8_t ret = 0;
538
    BTN_STATUS btns;
520
    BTN_STATUS btns;
539
    switch (c) {
521
    switch (c) {
540
        case CMD_QUERY_BTN:
522
        case CMD_QUERY_BTN:
541
            Pins_Read(&btns);
523
            Pins_Read(&btns);
542
            i2c_data_p->buffer_out[0] = btns.value;
524
            i2c_data_p->buffer_out[0] = btns.value;