Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 234 → Rev 235

/PIC Stuff/Cerebot_32MX7_LED_Cube/I2C1.c
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;
}
}