i2c_master: fix 1 byte read
This commit is contained in:
parent
25ce80b73a
commit
4bfcca9d50
|
@ -433,14 +433,10 @@ enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size
|
||||||
return I2C_MASTER_RC_NOT_READY;
|
return I2C_MASTER_RC_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prepare (N)ACK (EV6_3 in RM0008)
|
||||||
if (1 == data_size) {
|
if (1 == data_size) {
|
||||||
i2c_nack_current(i2c); // [N]ACK current byte
|
|
||||||
i2c_disable_ack(i2c); // NACK after first 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 {
|
} else {
|
||||||
i2c_nack_current(i2c); // ACK current byte
|
|
||||||
i2c_enable_ack(i2c); // NAK after next byte
|
i2c_enable_ack(i2c); // NAK after next byte
|
||||||
}
|
}
|
||||||
uint16_t sr2 = I2C_SR2(i2c); // reading SR2 will also also clear ADDR in SR1 and start the transaction
|
uint16_t sr2 = I2C_SR2(i2c); // reading SR2 will also also clear ADDR in SR1 and start the transaction
|
||||||
|
@ -453,11 +449,13 @@ enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size
|
||||||
|
|
||||||
// read data
|
// read data
|
||||||
for (size_t i = 0; i < data_size; i++) { // read bytes
|
for (size_t i = 0; i < data_size; i++) { // read bytes
|
||||||
if (2 == data_size - i) { // prepare to sent NACK for second last byte
|
// set (N)ACK (EV6_3, EV6_1)
|
||||||
i2c_nack_next(i2c); // NACK next byte
|
if (1 == data_size - i) { // prepare to sent NACK for last byte
|
||||||
|
i2c_send_stop(i2c); // already indicate we will send a stop (required to not send an ACK, and this must happen before the byte is transferred, see errata)
|
||||||
|
i2c_nack_current(i2c); // (N)ACK current byte
|
||||||
i2c_disable_ack(i2c); // NACK received to stop slave transmission
|
i2c_disable_ack(i2c); // NACK received to stop slave transmission
|
||||||
} else if (1 == data_size - i) { // prepare to sent NACK for last byte
|
} else if (2 == data_size - i) { // prepare to sent NACK for second last byte
|
||||||
i2c_nack_current(i2c); // ACK current byte
|
i2c_nack_next(i2c); // NACK next byte
|
||||||
i2c_disable_ack(i2c); // NACK received to stop slave transmission
|
i2c_disable_ack(i2c); // NACK received to stop slave transmission
|
||||||
} else {
|
} else {
|
||||||
i2c_enable_ack(i2c); // ACK received byte to continue slave transmission
|
i2c_enable_ack(i2c); // ACK received byte to continue slave transmission
|
||||||
|
|
|
@ -69,20 +69,21 @@ enum i2c_master_rc i2c_master_start(uint32_t i2c);
|
||||||
*/
|
*/
|
||||||
enum i2c_master_rc i2c_master_select_slave(uint32_t i2c, uint16_t slave, bool address_10bit, bool write);
|
enum i2c_master_rc i2c_master_select_slave(uint32_t i2c, uint16_t slave, bool address_10bit, bool write);
|
||||||
/** read data over I²C
|
/** read data over I²C
|
||||||
* @warning the slave device must be selected before this operation
|
|
||||||
* @param[in] i2c I²C base address
|
* @param[in] i2c I²C base address
|
||||||
* @param[out] data array to store bytes read
|
* @param[out] data array to store bytes read
|
||||||
* @param[in] data_size number of bytes to read
|
* @param[in] data_size number of bytes to read
|
||||||
* @note the last read byte is NACKed, but the I²C peripheral will clock the read for at least 2 more bytes after the NACK
|
|
||||||
* @return I²C return code
|
* @return I²C return code
|
||||||
|
* @warning the slave device must be selected before this operation
|
||||||
|
* @note a stop condition will be sent at the end (I²C does not permit multiple reads, and this is necessary for 1-byte transfer)
|
||||||
*/
|
*/
|
||||||
enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size);
|
enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size);
|
||||||
/** write data over I²C
|
/** write data over I²C
|
||||||
* @warning the slave device must be selected before this operation
|
|
||||||
* @param[in] i2c I²C base address
|
* @param[in] i2c I²C base address
|
||||||
* @param[in] data array of byte to write to slave
|
* @param[in] data array of byte to write to slave
|
||||||
* @param[in] data_size number of bytes to write
|
* @param[in] data_size number of bytes to write
|
||||||
* @return I²C return code
|
* @return I²C return code
|
||||||
|
* @warning the slave device must be selected before this operation
|
||||||
|
* @note no stop condition is sent at the end, allowing multiple writes
|
||||||
*/
|
*/
|
||||||
enum i2c_master_rc i2c_master_write(uint32_t i2c, const uint8_t* data, size_t data_size);
|
enum i2c_master_rc i2c_master_write(uint32_t i2c, const uint8_t* data, size_t data_size);
|
||||||
/** sent stop condition
|
/** sent stop condition
|
||||||
|
@ -97,6 +98,7 @@ enum i2c_master_rc i2c_master_stop(uint32_t i2c);
|
||||||
* @param[out] data array to store bytes read
|
* @param[out] data array to store bytes read
|
||||||
* @param[in] data_size number of bytes to read
|
* @param[in] data_size number of bytes to read
|
||||||
* @return I²C return code
|
* @return I²C return code
|
||||||
|
* @note start and stop conditions are included
|
||||||
*/
|
*/
|
||||||
enum i2c_master_rc i2c_master_slave_read(uint32_t i2c, uint16_t slave, bool address_10bit, uint8_t* data, size_t data_size);
|
enum i2c_master_rc i2c_master_slave_read(uint32_t i2c, uint16_t slave, bool address_10bit, uint8_t* data, size_t data_size);
|
||||||
/** write data to slave device
|
/** write data to slave device
|
||||||
|
@ -106,6 +108,7 @@ enum i2c_master_rc i2c_master_slave_read(uint32_t i2c, uint16_t slave, bool addr
|
||||||
* @param[in] data array of byte to write to slave
|
* @param[in] data array of byte to write to slave
|
||||||
* @param[in] data_size number of bytes to write
|
* @param[in] data_size number of bytes to write
|
||||||
* @return I²C return code
|
* @return I²C return code
|
||||||
|
* @note start and stop conditions are included
|
||||||
*/
|
*/
|
||||||
enum i2c_master_rc i2c_master_slave_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* data, size_t data_size);
|
enum i2c_master_rc i2c_master_slave_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* data, size_t data_size);
|
||||||
/** read data at specific address from an I²C memory slave
|
/** read data at specific address from an I²C memory slave
|
||||||
|
@ -117,6 +120,7 @@ enum i2c_master_rc i2c_master_slave_write(uint32_t i2c, uint16_t slave, bool add
|
||||||
* @param[out] data array to store bytes read
|
* @param[out] data array to store bytes read
|
||||||
* @param[in] data_size number of bytes to read
|
* @param[in] data_size number of bytes to read
|
||||||
* @return I²C return code
|
* @return I²C return code
|
||||||
|
* @note start and stop conditions are included
|
||||||
*/
|
*/
|
||||||
enum i2c_master_rc i2c_master_address_read(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size);
|
enum i2c_master_rc i2c_master_address_read(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size);
|
||||||
/** write data at specific address on an I²C memory slave
|
/** write data at specific address on an I²C memory slave
|
||||||
|
@ -128,5 +132,6 @@ enum i2c_master_rc i2c_master_address_read(uint32_t i2c, uint16_t slave, bool ad
|
||||||
* @param[in] data array of byte to write to slave
|
* @param[in] data array of byte to write to slave
|
||||||
* @param[in] data_size number of bytes to write
|
* @param[in] data_size number of bytes to write
|
||||||
* @return I²C return code
|
* @return I²C return code
|
||||||
|
* @note start and stop conditions are included
|
||||||
*/
|
*/
|
||||||
enum i2c_master_rc i2c_master_address_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size);
|
enum i2c_master_rc i2c_master_address_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size);
|
||||||
|
|
Loading…
Reference in New Issue