i2c_master: fix writing function to cope with read function now including a stop

This commit is contained in:
King Kévin 2020-02-27 13:06:29 +01:00
parent 29226246f6
commit 4b1651a1a3
1 changed files with 31 additions and 13 deletions

View File

@ -670,22 +670,39 @@ enum i2c_master_rc i2c_master_address_read(uint32_t i2c, uint16_t slave, bool ad
if (I2C_MASTER_RC_NONE != rc) {
goto error;
}
rc = i2c_master_read(i2c, data, data_size); // read memory
rc = i2c_master_read(i2c, data, data_size); // read memory (includes stop)
if (I2C_MASTER_RC_NONE != rc) {
goto error;
}
} else {
i2c_master_stop(i2c); // sent stop condition
}
rc = I2C_MASTER_RC_NONE; // all went well
rc = I2C_MASTER_RC_NONE;
error:
i2c_master_stop(i2c); // sent stop condition
if (I2C_MASTER_RC_NONE != rc) { // only send stop on error
i2c_master_stop(i2c); // sent stop condition
}
return rc;
}
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)
{
cm3_assert(I2C1 == i2c || I2C2 == i2c);
if (SIZE_MAX - address_size < data_size) { // prevent integer overflow
return I2C_MASTER_RC_OTHER;
}
if (address_size + data_size > 10 * 1024) { // we won't enough RAM
return I2C_MASTER_RC_OTHER;
}
if (address_size > 0 && NULL == address) {
return I2C_MASTER_RC_OTHER;
}
if (data_size > 0 && NULL == data) {
return I2C_MASTER_RC_OTHER;
}
uint8_t buffer[address_size + data_size];
enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I²C return codes
rc = i2c_master_start(i2c); // send (re-)start condition
if (I2C_MASTER_RC_NONE != rc) {
@ -696,20 +713,21 @@ enum i2c_master_rc i2c_master_address_write(uint32_t i2c, uint16_t slave, bool a
goto error;
}
// write address
if (NULL != address && address_size > 0) {
rc = i2c_master_write(i2c, address, address_size); // send memory address
if (I2C_MASTER_RC_NONE != rc) {
goto error;
// we can't send the address then the data size short address will cause a stop (because of how crappy the STM32F10x I²C peripheral is)
if (address) {
for (size_t i = 0; i < address_size; i++) {
buffer[i] = address[i];
}
}
// read data
if (NULL != data && data_size > 0) {
rc = i2c_master_write(i2c, data, data_size); // write memory
if (I2C_MASTER_RC_NONE != rc) {
goto error;
if (data) {
for (size_t i = 0; i < data_size; i++) {
buffer[address_size + i] = data[i];
}
}
rc = i2c_master_write(i2c, buffer, address_size + data_size); // send memory address
if (I2C_MASTER_RC_NONE != rc) {
goto error;
}
error:
rc = i2c_master_stop(i2c); // sent stop condition