From 9aa3b9f391d22fd6432f0638476193f83abf1209 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 25 Jul 2022 10:03:35 +0200 Subject: [PATCH] fix(wire): ensure i2c bus is ready Previously, i2c_master_write and i2c_master_read returned I2C_OK if first HAL call returned HAL_BUSY which was not correct. Now make sure the i2c is ready, which guarantees a good initialization of the read or write sequence. Fixes #1774 Signed-off-by: Frederic Pillon --- libraries/Wire/src/utility/twi.c | 42 +++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/libraries/Wire/src/utility/twi.c b/libraries/Wire/src/utility/twi.c index cf9b8c535e..d349df3c20 100644 --- a/libraries/Wire/src/utility/twi.c +++ b/libraries/Wire/src/utility/twi.c @@ -848,6 +848,7 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address, uint32_t tickstart = HAL_GetTick(); uint32_t delta = 0; uint32_t err = 0; + HAL_StatusTypeDef status = HAL_OK; /* When size is 0, this is usually an I2C scan / ping to check if device is there and ready */ if (size == 0) { @@ -856,12 +857,26 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address, #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 defined(I2C_OTHER_FRAME) - if (HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_OK) { + status = HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size, XferOptions); #else - if (HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size) == HAL_OK) { + status = HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size); #endif + // Ensure i2c ready + if (status == HAL_BUSY) { + delta = (HAL_GetTick() - tickstart); + if (delta > I2C_TIMEOUT_TICK) { + ret = I2C_BUSY; + break; + } + } else { + ret = (status == HAL_OK) ? I2C_OK : I2C_ERROR; + } + } while (status == HAL_BUSY); + + if (ret == I2C_OK) { + tickstart = HAL_GetTick(); // wait for transfer completion while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) && (delta < I2C_TIMEOUT_TICK)) { delta = (HAL_GetTick() - tickstart); @@ -926,16 +941,31 @@ 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; uint32_t err = 0; + HAL_StatusTypeDef status = HAL_OK; #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 defined(I2C_OTHER_FRAME) - if (HAL_I2C_Master_Seq_Receive_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_OK) { + status = HAL_I2C_Master_Seq_Receive_IT(&(obj->handle), dev_address, data, size, XferOptions); #else - if (HAL_I2C_Master_Receive_IT(&(obj->handle), dev_address, data, size) == HAL_OK) { + status = HAL_I2C_Master_Receive_IT(&(obj->handle), dev_address, data, size); #endif + // Ensure i2c ready + if (status == HAL_BUSY) { + delta = (HAL_GetTick() - tickstart); + if (delta > I2C_TIMEOUT_TICK) { + ret = I2C_BUSY; + break; + } + } else { + ret = (status == HAL_OK) ? I2C_OK : I2C_ERROR; + } + } while (status == HAL_BUSY); + + if (ret == I2C_OK) { + tickstart = HAL_GetTick(); // wait for transfer completion while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) && (delta < I2C_TIMEOUT_TICK)) { delta = (HAL_GetTick() - tickstart); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy