40,6 → 40,7 |
} |
|
// Sends length number of bytes in msg to specified address (no R/W bit) |
// Will return status I2C1_SEND_OK or I2C1_SEND_FAIL |
void I2C1_Master_Send(uint8_t address, uint8_t *msg, uint32_t length) { |
uint32_t i; |
if (length == 0) |
63,6 → 64,7 |
} |
|
// Reads length number of bytes from address (no R/W bit) |
// Will return status I2C1_RECV_OK or I2C1_RECV_FAIL |
void I2C1_Master_Recv(uint8_t address, uint32_t length) { |
if (length == 0) |
return; |
82,6 → 84,7 |
} |
|
// Writes msg to address then reads length number of bytes from address |
// Will return status I2C1_SEND_FAIL or I2C1_RECV_FAIL or I2C1_RECV_OK |
void I2C1_Master_Restart(uint8_t address, uint8_t msg, uint32_t length) { |
uint8_t c; |
if (length == 0) { |
137,6 → 140,11 |
* 7. During a slave-detected stop |
*/ |
|
if (I2C1STATbits.IWCOL == 1) { |
// TODO: Handle write collisions |
I2C1STATbits.IWCOL = 0; |
} |
|
// If we are in the middle of sending data |
if (i2c_data_p->master_status == I2C1_MASTER_SEND) { |
switch (i2c_data_p->operating_state) { |
156,19 → 164,21 |
i2c_data_p->buffer_in_read_ind++; |
} else { |
// If no more data is to be sent, send stop bit |
i2c_data_p->operating_state = I2C1_IDLE; |
i2c_data_p->operating_state = I2C1_STOPPED; |
I2C1CONbits.PEN = 1; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
i2c_data_p->return_status = I2C1_SEND_OK; |
} |
} else { |
// If a NACK is received, stop transmission and send error |
i2c_data_p->operating_state = I2C1_IDLE; |
i2c_data_p->operating_state = I2C1_STOPPED; |
I2C1CONbits.PEN = 1; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
i2c_data_p->return_status = I2C1_SEND_FAIL; |
} |
break; |
case I2C1_STOPPED: |
i2c_data_p->operating_state = I2C1_IDLE; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
break; |
} |
// If we are in the middle of receiving data |
} else if (i2c_data_p->master_status == I2C1_MASTER_RECV) { |
188,15 → 198,14 |
I2C1CONbits.RCEN = 1; |
} else { |
// If a NACK is received, stop transmission and send error |
i2c_data_p->operating_state = I2C1_IDLE; |
i2c_data_p->operating_state = I2C1_STOPPED; |
I2C1CONbits.PEN = 1; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
i2c_data_p->return_status = I2C1_RECV_FAIL; |
} |
break; |
case I2C1_RCV_DATA: |
// On receive, save byte into buffer |
// TODO: Handle I2C buffer overflow |
// TODO: Handle possible I2C buffer overflow |
i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = I2C1RCV; |
i2c_data_p->buffer_in_write_ind++; |
if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) { |
217,12 → 226,15 |
I2C1CONbits.RCEN = 1; |
break; |
case I2C1_SEND_STOP: |
// Send the stop bit and copy message to send to Main() |
i2c_data_p->operating_state = I2C1_IDLE; |
// Send the stop bit |
i2c_data_p->operating_state = I2C1_STOPPED; |
I2C1CONbits.PEN = 1; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
i2c_data_p->return_status = I2C1_RECV_OK; |
break; |
case I2C1_STOPPED: |
i2c_data_p->operating_state = I2C1_IDLE; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
break; |
} |
} else if (i2c_data_p->master_status == I2C1_MASTER_RESTART) { |
switch (i2c_data_p->operating_state) { |
241,9 → 253,8 |
i2c_data_p->operating_state = I2C1_CHECK_ACK_RESTART; |
} else { |
// If a NACK is received, stop transmission and send error |
i2c_data_p->operating_state = I2C1_IDLE; |
i2c_data_p->operating_state = I2C1_STOPPED; |
I2C1CONbits.PEN = 1; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
i2c_data_p->return_status = I2C1_SEND_FAIL; |
} |
break; |
253,9 → 264,8 |
i2c_data_p->operating_state = I2C1_SEND_ADDR_2; |
} else { |
// If a NACK is received, stop transmission and send error |
i2c_data_p->operating_state = I2C1_IDLE; |
i2c_data_p->operating_state = I2C1_STOPPED; |
I2C1CONbits.PEN = 1; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
i2c_data_p->return_status = I2C1_SEND_FAIL; |
} |
break; |
272,15 → 282,14 |
I2C1CONbits.RCEN = 1; |
} else { |
// If a NACK is received, stop transmission and send error |
i2c_data_p->operating_state = I2C1_IDLE; |
i2c_data_p->operating_state = I2C1_STOPPED; |
I2C1CONbits.PEN = 1; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
i2c_data_p->return_status = I2C1_RECV_FAIL; |
} |
break; |
case I2C1_RCV_DATA: |
// On receive, save byte into buffer |
// TODO: Handle I2C buffer overflow |
// TODO: Handle possible I2C buffer overflow |
i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = I2C1RCV; |
i2c_data_p->buffer_in_write_ind++; |
if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) { |
301,12 → 310,15 |
I2C1CONbits.RCEN = 1; |
break; |
case I2C1_SEND_STOP: |
// Send the stop bit and copy message to send to Main() |
i2c_data_p->operating_state = I2C1_IDLE; |
// Send the stop bit |
i2c_data_p->operating_state = I2C1_STOPPED; |
I2C1CONbits.PEN = 1; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
i2c_data_p->return_status = I2C1_RECV_OK; |
break; |
case I2C1_STOPPED: |
i2c_data_p->operating_state = I2C1_IDLE; |
i2c_data_p->master_status = I2C1_MASTER_IDLE; |
break; |
} |
} |
} |
399,11 → 411,12 |
|
/* Returns 0 if I2C module is currently busy, otherwise returns status code */ |
uint8_t I2C1_Get_Status() { |
if (i2c_data_p->master_status != I2C1_MASTER_IDLE || |
i2c_data_p->buffer_in_len == 0) { |
if (i2c_data_p->master_status == I2C1_MASTER_IDLE && |
i2c_data_p->operating_state == I2C1_IDLE && |
I2C1STATbits.TBF == 0) { |
return i2c_data_p->return_status; |
} else { |
return 0; |
} else { |
return i2c_data_p->return_status; |
} |
} |
|