From 4b1651a1a37fe6d092d3eb37cadc977956bf89d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Thu, 27 Feb 2020 13:06:29 +0100 Subject: [PATCH] i2c_master: fix writing function to cope with read function now including a stop --- lib/i2c_master.c | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/lib/i2c_master.c b/lib/i2c_master.c index a65bd31..5172cfe 100644 --- a/lib/i2c_master.c +++ b/lib/i2c_master.c @@ -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