From 760f7aa288422cedeab9a0b408f03bd84f6e9b3e Mon Sep 17 00:00:00 2001 From: Jean-Marc Date: Sat, 3 Aug 2019 13:50:18 +0200 Subject: [PATCH 1/6] Added the repeated-start feature in I2C driver --- cores/arduino/stm32/twi.c | 4 ++-- libraries/Wire/src/Wire.cpp | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/cores/arduino/stm32/twi.c b/cores/arduino/stm32/twi.c index 01c6b3912d..ee085d0245 100644 --- a/cores/arduino/stm32/twi.c +++ b/cores/arduino/stm32/twi.c @@ -717,7 +717,7 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address, } do { - if (HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size) == HAL_OK) { + if (HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size,obj->handle.XferOptions) == HAL_OK) { ret = I2C_OK; // wait for transfer completion while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) @@ -778,7 +778,7 @@ i2c_status_e i2c_master_read(i2c_t *obj, uint8_t dev_address, uint8_t *data, uin uint32_t delta = 0; do { - if (HAL_I2C_Master_Receive_IT(&(obj->handle), dev_address, data, size) == HAL_OK) { + if (HAL_I2C_Master_Seq_Receive_IT(&(obj->handle), dev_address, data, size, obj->handle.XferOptions) == HAL_OK) { ret = I2C_OK; // wait for transfer completion while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 77d20894b8..9bee2ff943 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -27,6 +27,7 @@ extern "C" { #include "Wire.h" +#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */ // Initialize Class Variables ////////////////////////////////////////////////// uint8_t *TwoWire::rxBuffer = nullptr; uint8_t TwoWire::rxBufferAllocated = 0; @@ -116,7 +117,6 @@ void TwoWire::setClock(uint32_t frequency) uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) { - UNUSED(sendStop); if (_i2c.isMaster == 1) { allocateRxBuffer(quantity); // error if no memory block available to allocate the buffer @@ -146,6 +146,11 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres // perform blocking read into buffer uint8_t read = 0; + if(sendStop!=false) { + _i2c.handle.XferOptions = I2C_LAST_FRAME; + }else{ + _i2c.handle.XferOptions = I2C_NO_OPTION_FRAME; + } if (I2C_OK == i2c_master_read(&_i2c, address << 1, rxBuffer, quantity)) { read = quantity; } @@ -211,8 +216,14 @@ void TwoWire::beginTransmission(int address) // uint8_t TwoWire::endTransmission(uint8_t sendStop) { - UNUSED(sendStop); + //UNUSED(sendStop); int8_t ret = 4; + // check transfer options and store it in the I2C handle + if(sendStop==false) { + _i2c.handle.XferOptions = I2C_FIRST_FRAME; + }else{ + _i2c.handle.XferOptions = I2C_FIRST_AND_LAST_FRAME; + } if (_i2c.isMaster == 1) { // transmit buffer (blocking) From 7b63e8cbd41ebc59c9e206eba74ff9beb96b9589 Mon Sep 17 00:00:00 2001 From: Jean-Marc Date: Sat, 3 Aug 2019 14:04:34 +0200 Subject: [PATCH 2/6] fixed Astyle issues --- cores/arduino/stm32/twi.c | 2 +- libraries/Wire/src/Wire.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cores/arduino/stm32/twi.c b/cores/arduino/stm32/twi.c index ee085d0245..6bef236db8 100644 --- a/cores/arduino/stm32/twi.c +++ b/cores/arduino/stm32/twi.c @@ -717,7 +717,7 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address, } do { - if (HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size,obj->handle.XferOptions) == HAL_OK) { + if (HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size, obj->handle.XferOptions) == HAL_OK) { ret = I2C_OK; // wait for transfer completion while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 9bee2ff943..9e2a2505d3 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -146,9 +146,9 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres // perform blocking read into buffer uint8_t read = 0; - if(sendStop!=false) { + if (sendStop != false) { _i2c.handle.XferOptions = I2C_LAST_FRAME; - }else{ + } else { _i2c.handle.XferOptions = I2C_NO_OPTION_FRAME; } if (I2C_OK == i2c_master_read(&_i2c, address << 1, rxBuffer, quantity)) { @@ -219,9 +219,9 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop) //UNUSED(sendStop); int8_t ret = 4; // check transfer options and store it in the I2C handle - if(sendStop==false) { + if (sendStop == false) { _i2c.handle.XferOptions = I2C_FIRST_FRAME; - }else{ + } else { _i2c.handle.XferOptions = I2C_FIRST_AND_LAST_FRAME; } From 22379d1c557e4417f9a6cc10d87ae0164c281aa2 Mon Sep 17 00:00:00 2001 From: Jean-Marc CHIAPPA Date: Sun, 1 Sep 2019 19:40:07 +0200 Subject: [PATCH 3/6] Update libraries/Wire/src/Wire.cpp Co-Authored-By: Frederic Pillon --- libraries/Wire/src/Wire.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 9e2a2505d3..c774fcfc29 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -216,7 +216,6 @@ void TwoWire::beginTransmission(int address) // uint8_t TwoWire::endTransmission(uint8_t sendStop) { - //UNUSED(sendStop); int8_t ret = 4; // check transfer options and store it in the I2C handle if (sendStop == false) { From b76a180cbd201db011da222dbc9baff2e5fd7db3 Mon Sep 17 00:00:00 2001 From: Jean-Marc CHIAPPA Date: Wed, 4 Sep 2019 10:43:49 +0200 Subject: [PATCH 4/6] Update libraries/Wire/src/Wire.cpp Co-Authored-By: Frederic Pillon --- libraries/Wire/src/Wire.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index c774fcfc29..067a810145 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -146,7 +146,7 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres // perform blocking read into buffer uint8_t read = 0; - if (sendStop != false) { + if (sendStop != 0) { _i2c.handle.XferOptions = I2C_LAST_FRAME; } else { _i2c.handle.XferOptions = I2C_NO_OPTION_FRAME; From 551f9083d085274e83de6704a53d949d5d12aa94 Mon Sep 17 00:00:00 2001 From: Jean-Marc CHIAPPA Date: Wed, 4 Sep 2019 10:43:57 +0200 Subject: [PATCH 5/6] Update libraries/Wire/src/Wire.cpp Co-Authored-By: Frederic Pillon --- libraries/Wire/src/Wire.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 067a810145..2f1b56a5bd 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -218,7 +218,7 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop) { int8_t ret = 4; // check transfer options and store it in the I2C handle - if (sendStop == false) { + if (sendStop == 0) { _i2c.handle.XferOptions = I2C_FIRST_FRAME; } else { _i2c.handle.XferOptions = I2C_FIRST_AND_LAST_FRAME; From 1bb59af1866967ccf433585a42a9eaf0d85035fe Mon Sep 17 00:00:00 2001 From: Alexandre Bourdiol Date: Wed, 4 Sep 2019 11:08:45 +0200 Subject: [PATCH 6/6] update on PR Added the repeated-start feature in I2C driver #590 --- cores/arduino/stm32/twi.c | 20 ++++++++++++++++++-- libraries/Wire/src/Wire.cpp | 24 ++++++++++++++++++------ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/cores/arduino/stm32/twi.c b/cores/arduino/stm32/twi.c index 6bef236db8..cd4723252a 100644 --- a/cores/arduino/stm32/twi.c +++ b/cores/arduino/stm32/twi.c @@ -716,8 +716,16 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address, return i2c_IsDeviceReady(obj, dev_address, 1); } +#if defined(I2C_OTHER_FRAME) + uint32_t XferOptions = obj->handle.XferOptions; // save XferOptions value, because handle can be modified by HAL, which cause issue in case of NACK from slave +#endif + do { - if (HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size, obj->handle.XferOptions) == HAL_OK) { +#if defined(I2C_OTHER_FRAME) + if (HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_OK) { +#else + if (HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size) == HAL_OK) { +#endif ret = I2C_OK; // wait for transfer completion while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) @@ -777,8 +785,16 @@ i2c_status_e i2c_master_read(i2c_t *obj, uint8_t dev_address, uint8_t *data, uin uint32_t tickstart = HAL_GetTick(); uint32_t delta = 0; +#if defined(I2C_OTHER_FRAME) + uint32_t XferOptions = obj->handle.XferOptions; // save XferOptions value, because handle can be modified by HAL, which cause issue in case of NACK from slave +#endif + do { - if (HAL_I2C_Master_Seq_Receive_IT(&(obj->handle), dev_address, data, size, obj->handle.XferOptions) == HAL_OK) { +#if defined(I2C_OTHER_FRAME) + if (HAL_I2C_Master_Seq_Receive_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_OK) { +#else + if (HAL_I2C_Master_Receive_IT(&(obj->handle), dev_address, data, size) == HAL_OK) { +#endif ret = I2C_OK; // wait for transfer completion while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 2f1b56a5bd..ca10141b35 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -27,7 +27,6 @@ extern "C" { #include "Wire.h" -#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */ // Initialize Class Variables ////////////////////////////////////////////////// uint8_t *TwoWire::rxBuffer = nullptr; uint8_t TwoWire::rxBufferAllocated = 0; @@ -117,6 +116,10 @@ void TwoWire::setClock(uint32_t frequency) uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) { +#if !defined(I2C_OTHER_FRAME) + UNUSED(sendStop); +#endif + if (_i2c.isMaster == 1) { allocateRxBuffer(quantity); // error if no memory block available to allocate the buffer @@ -146,11 +149,15 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres // perform blocking read into buffer uint8_t read = 0; - if (sendStop != 0) { - _i2c.handle.XferOptions = I2C_LAST_FRAME; + +#if defined(I2C_OTHER_FRAME) + if (sendStop == 0) { + _i2c.handle.XferOptions = I2C_OTHER_FRAME ; } else { - _i2c.handle.XferOptions = I2C_NO_OPTION_FRAME; + _i2c.handle.XferOptions = I2C_OTHER_AND_LAST_FRAME; } +#endif + if (I2C_OK == i2c_master_read(&_i2c, address << 1, rxBuffer, quantity)) { read = quantity; } @@ -216,13 +223,18 @@ void TwoWire::beginTransmission(int address) // uint8_t TwoWire::endTransmission(uint8_t sendStop) { +#if !defined(I2C_OTHER_FRAME) + UNUSED(sendStop); +#endif int8_t ret = 4; // check transfer options and store it in the I2C handle +#if defined(I2C_OTHER_FRAME) if (sendStop == 0) { - _i2c.handle.XferOptions = I2C_FIRST_FRAME; + _i2c.handle.XferOptions = I2C_OTHER_FRAME ; } else { - _i2c.handle.XferOptions = I2C_FIRST_AND_LAST_FRAME; + _i2c.handle.XferOptions = I2C_OTHER_AND_LAST_FRAME; } +#endif if (_i2c.isMaster == 1) { // transmit buffer (blocking)