29,7 → 29,7 |
} |
|
// Setup the PIC to operate as a master. |
void I2C_Configure_Master() { |
void I2C_Configure_Master(unsigned char speed) { |
i2c_data.operating_mode = I2C_MODE_MASTER; |
|
TRISCbits.TRISC3 = 1; |
39,7 → 39,11 |
SSPCON1 = 0x0; |
SSPCON2 = 0x0; |
SSPCON1bits.SSPM = 0x8; // I2C Master Mode |
SSPADD = 0x77; // Operate at 100KHz (48MHz) |
if (speed) { |
SSPADD = 0x74; // Operate at 100KHz (48MHz) |
} else { |
SSPADD = 0x1A; // Operate at 400KHz (48MHz) |
} |
SSPSTATbits.SMP = 1; // Disable Slew Rate Control |
SSPCON1bits.SSPEN = 1; // Enable MSSP Module |
} |
57,6 → 61,7 |
i2c_data.buffer_in_len = length; |
i2c_data.master_dest_addr = address; |
i2c_data.buffer_in_read_ind = 0; |
i2c_data.buffer_in_write_ind = 0; |
|
// Change status to 'next' operation |
i2c_data.operating_state = I2C_SEND_ADDR; |
75,6 → 80,7 |
i2c_data.buffer_in_len = length; |
i2c_data.master_dest_addr = address; |
i2c_data.buffer_in_read_ind = 0; |
i2c_data.buffer_in_write_ind = 0; |
|
// Change status to 'next' operation |
i2c_data.operating_state = I2C_SEND_ADDR; |
98,6 → 104,7 |
i2c_data.buffer_in_len = length; |
i2c_data.master_dest_addr = address; |
i2c_data.buffer_in_read_ind = 0; |
i2c_data.buffer_in_write_ind = 0; |
|
// Change status to 'next' operation |
i2c_data.operating_state = I2C_SEND_ADDR; |
196,9 → 203,10 |
break; |
case I2C_RCV_DATA: |
// On receive, save byte into buffer |
i2c_data.buffer_in[i2c_data.buffer_in_read_ind] = SSPBUF; |
i2c_data.buffer_in_read_ind++; |
if (i2c_data.buffer_in_read_ind < i2c_data.buffer_in_len) { |
// TODO: handle i2c buffer overflow |
i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = SSPBUF; |
i2c_data.buffer_in_write_ind++; |
if (i2c_data.buffer_in_write_ind < i2c_data.buffer_in_len) { |
// If we still need to read, send an ACK to the slave |
i2c_data.operating_state = I2C_REQ_DATA; |
SSPCON2bits.ACKDT = 0; // ACK |
279,9 → 287,10 |
break; |
case I2C_RCV_DATA: |
// On receive, save byte into buffer |
i2c_data.buffer_in[i2c_data.buffer_in_read_ind] = SSPBUF; |
i2c_data.buffer_in_read_ind++; |
if (i2c_data.buffer_in_read_ind < i2c_data.buffer_in_len) { |
// TODO: handle i2c buffer overflow |
i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = SSPBUF; |
i2c_data.buffer_in_write_ind++; |
if (i2c_data.buffer_in_write_ind < i2c_data.buffer_in_len) { |
// If we still need to read, send an ACK to the slave |
i2c_data.operating_state = I2C_REQ_DATA; |
SSPCON2bits.ACKDT = 0; // ACK |
317,7 → 326,7 |
|
// Clear SSPOV (overflow bit) |
if (SSPCON1bits.SSPOV == 1) { |
// DBG_PRINT_I2C("I2C: overflow detected\r\n"); |
DBG_PRINT_I2C("I2C: overflow detected\r\n"); |
SSPCON1bits.SSPOV = 0; |
// We failed to read the buffer in time, so we know we |
// can't properly receive this message, just put us in the |
330,7 → 339,7 |
// Read SPPxBUF if it is full |
if (SSPSTATbits.BF == 1) { |
received_data = SSPBUF; |
// DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF); |
DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF); |
data_read_from_buffer = 1; |
} |
|
344,7 → 353,7 |
i2c_data.operating_state = I2C_STARTED; |
// if (data_read_from_buffer) { |
// if (SSPSTATbits.D_A == 1) { |
//// DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n"); |
// DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n"); |
// // This is bad because we got data and we wanted an address |
// i2c_data.operating_state = I2C_IDLE; |
// i2c_data.return_status = I2C_ERR_NOADDR; |
381,7 → 390,7 |
goto send; |
} |
} else { |
// DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n"); |
DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n"); |
i2c_data.operating_state = I2C_IDLE; |
i2c_data.return_status = I2C_ERR_NODATA; |
} |
426,6 → 435,7 |
if (data_read_from_buffer) { |
if (SSPSTATbits.D_A == 1) { |
// Data received with stop bit |
// TODO: handle i2c buffer overflow |
i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = received_data; |
if (i2c_data.buffer_in_write_ind == MAXI2CBUF-1) { |
i2c_data.buffer_in_write_ind = 0; |
437,7 → 447,7 |
i2c_data.slave_in_last_byte = received_data; |
i2c_data.return_status = I2C_DATA_AVAL; |
} else { |
// DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n"); |
DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n"); |
i2c_data.operating_state = I2C_IDLE; |
i2c_data.return_status = I2C_ERR_NODATA; |
} |
466,7 → 476,7 |
goto send; |
} else { |
// Bad to recv an address again, we aren't ready |
// DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n"); |
DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n"); |
i2c_data.operating_state = I2C_IDLE; |
i2c_data.return_status = I2C_ERR_NODATA; |
} |
503,6 → 513,10 |
} |
} |
|
unsigned char I2C_Buffer_Len() { |
return i2c_data.buffer_in_len; |
} |
|
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */ |
unsigned char I2C_Read_Buffer(char *buffer) { |
unsigned char i = 0; |