I2C: fix read NACK
NACKing in receive mode is different when 1, 2, or more bytes are read. see the reference manual for the cases and how to handle them.
This commit is contained in:
parent
bf2eca0401
commit
a50a181b86
|
@ -417,7 +417,18 @@ enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size
|
|||
// sanity check
|
||||
if (data==NULL || data_size==0) { // no data to read
|
||||
return I2C_MASTER_RC_NONE;
|
||||
}
|
||||
}
|
||||
if (1 == data_size) {
|
||||
i2c_nack_current(i2c); // [N]ACK current byte
|
||||
i2c_disable_ack(i2c); // NACK after first byte
|
||||
} else if (2 == data_size) {
|
||||
i2c_nack_next(i2c); // [N]ACK next byte
|
||||
i2c_enable_ack(i2c); // NACK first byte
|
||||
} else {
|
||||
i2c_nack_current(i2c); // ACK current byte
|
||||
i2c_enable_ack(i2c); // NAK after next byte
|
||||
}
|
||||
// reading SR2 will also also clear ADDR and start the transaction
|
||||
if (!(I2C_SR2(i2c) & I2C_SR2_MSL)) { // I2C device is not master
|
||||
return I2C_MASTER_RC_NOT_MASTER;
|
||||
}
|
||||
|
@ -430,7 +441,11 @@ enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size
|
|||
|
||||
// read data
|
||||
for (size_t i=0; i<data_size; i++) { // read bytes
|
||||
if (i==data_size-1) { // prepare to sent NACK for last byte
|
||||
if (2 == data_size - i) { // prepare to sent NACK for second last byte
|
||||
i2c_nack_next(i2c); // NACK next byte
|
||||
i2c_disable_ack(i2c); // NACK received to stop slave transmission
|
||||
} else if (1 == data_size - i) { // prepare to sent NACK for last byte
|
||||
i2c_nack_current(i2c); // ACK current byte
|
||||
i2c_disable_ack(i2c); // NACK received to stop slave transmission
|
||||
} else {
|
||||
i2c_enable_ack(i2c); // ACK received byte to continue slave transmission
|
||||
|
|
|
@ -73,6 +73,7 @@ enum i2c_master_rc i2c_master_select_slave(uint32_t i2c, uint16_t slave, bool ad
|
|||
* @param[in] i2c I2C base address
|
||||
* @param[out] data array to store bytes read
|
||||
* @param[in] data_size number of bytes to read
|
||||
* @note the last read byte is NACKed, but the I2C peripheral will clock the read for at least 2 more bytes after the NACK
|
||||
* @return I2C return code
|
||||
*/
|
||||
enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size);
|
||||
|
|
Loading…
Reference in New Issue