From d317dfccbbb54c5c0f6e5dbd0286d84eb336d223 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 5 May 2021 16:20:53 +0200 Subject: [PATCH 1/2] make i2c_salve_read return the number of bytes read to let mbed-os read API return an error if less bytes are readed --- targets/TARGET_STM/TARGET_STM32H7/objects.h | 3 ++ targets/TARGET_STM/i2c_api.c | 49 ++++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32H7/objects.h b/targets/TARGET_STM/TARGET_STM32H7/objects.h index c07ced56dc..7da1c1a5ae 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/objects.h +++ b/targets/TARGET_STM/TARGET_STM32H7/objects.h @@ -117,6 +117,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/i2c_api.c b/targets/TARGET_STM/i2c_api.c index 85eacd9de3..9758d0ff9b 100644 --- a/targets/TARGET_STM/i2c_api.c +++ b/targets/TARGET_STM/i2c_api.c @@ -199,6 +199,10 @@ static I2C_HandleTypeDef *i2c_handles[I2C_NUM]; #define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) #endif +#define SLAVE_MODE_RECEIVE 1 +#define SLAVE_MODE_LISTEN 2 +#define DEFAULT_SLAVE_MODE SLAVE_MODE_LISTEN + /* Declare i2c_init_internal to be used in this file */ void i2c_init_internal(i2c_t *obj, const i2c_pinmap_t *pinmap); @@ -1199,7 +1203,7 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) #if DEVICE_I2CSLAVE /* restore slave address */ if (address != 0) { - obj_s->slave = 1; + obj_s->slave = DEFAULT_SLAVE_MODE; i2c_slave_address(obj, 0, address, 0); } #endif @@ -1251,7 +1255,7 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) I2C_HandleTypeDef *handle = &(obj_s->handle); if (enable_slave) { - obj_s->slave = 1; + obj_s->slave = DEFAULT_SLAVE_MODE; HAL_I2C_EnableListen_IT(handle); } else { obj_s->slave = 0; @@ -1295,11 +1299,28 @@ void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle) /* Get object ptr based on handler ptr */ i2c_t *obj = get_i2c_obj(I2cHandle); struct i2c_s *obj_s = I2C_S(obj); - obj_s->pending_slave_rx_maxter_tx = 0; + + if (obj_s->slave == SLAVE_MODE_LISTEN) { + obj_s->slave_rx_count++; + if (obj_s->slave_rx_count < obj_s->slave_rx_buffer_size){ + HAL_I2C_Slave_Seq_Receive_IT(I2cHandle, &(obj_s->slave_rx_buffer[obj_s->slave_rx_count]), 1, I2C_NEXT_FRAME); + } else { + obj_s->pending_slave_rx_maxter_tx = 0; + } + } else { + obj_s->pending_slave_rx_maxter_tx = 0; + } } void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) { + i2c_t *obj = get_i2c_obj(hi2c); + struct i2c_s *obj_s = I2C_S(obj); + + if (obj_s->slave == SLAVE_MODE_LISTEN) { + obj_s->pending_slave_rx_maxter_tx = 0; + } + /* restart listening for master requests */ HAL_I2C_EnableListen_IT(hi2c); } @@ -1328,18 +1349,34 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) int count = 0; int ret = 0; uint32_t timeout = 0; + int _length = 0; + + if (obj_s->slave == SLAVE_MODE_LISTEN) { + /* We don't know in advance how many bytes will be sent by master so + * we'll fetch one by one until master ends the sequence */ + _length = 1; + obj_s->slave_rx_buffer_size = length; + obj_s->slave_rx_count = 0; + obj_s->slave_rx_buffer = (uint8_t*)data; + } else { + _length = length; + } /* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */ - ret = HAL_I2C_Slave_Seq_Receive_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME); + ret = HAL_I2C_Slave_Seq_Receive_IT(handle, (uint8_t *) data, _length, I2C_NEXT_FRAME); if (ret == HAL_OK) { - timeout = BYTE_TIMEOUT_US * (length + 1); + timeout = BYTE_TIMEOUT_US * (_length + 1); while (obj_s->pending_slave_rx_maxter_tx && (--timeout != 0)) { wait_us(1); } if (timeout != 0) { - count = length; + if (obj_s->slave == SLAVE_MODE_LISTEN) { + count = obj_s->slave_rx_count; + } else { + count = _length; + } } else { DEBUG_PRINTF("TIMEOUT or error in i2c_slave_read\r\n"); } From cd35063694d1c260f7ce584ed3ae42493fd11804 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 3 Jun 2021 10:10:50 +0200 Subject: [PATCH 2/2] Add missing changes in objects.h file for others STM32 components --- targets/TARGET_STM/TARGET_STM32F0/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32F1/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32F2/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32F3/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32F4/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32F7/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32G0/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32G4/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32L0/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32L1/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32L4/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32L5/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32WB/objects.h | 3 +++ targets/TARGET_STM/TARGET_STM32WL/objects.h | 3 +++ 14 files changed, 42 insertions(+) diff --git a/targets/TARGET_STM/TARGET_STM32F0/objects.h b/targets/TARGET_STM/TARGET_STM32F0/objects.h index 08c0e5007d..a8e0fbc8be 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/objects.h @@ -98,6 +98,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32F1/objects.h b/targets/TARGET_STM/TARGET_STM32F1/objects.h index a85c815021..a1d5512b6b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/objects.h @@ -123,6 +123,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32F2/objects.h b/targets/TARGET_STM/TARGET_STM32F2/objects.h index 65d4484c83..25d7b62484 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F2/objects.h @@ -128,6 +128,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32F3/objects.h b/targets/TARGET_STM/TARGET_STM32F3/objects.h index 088aa8be6c..bca32ef268 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/objects.h @@ -113,6 +113,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32F4/objects.h b/targets/TARGET_STM/TARGET_STM32F4/objects.h index 8c42e83c0c..be2f3b3a31 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/objects.h @@ -112,6 +112,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32F7/objects.h b/targets/TARGET_STM/TARGET_STM32F7/objects.h index 3e485fb7e5..18789b8d9a 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/objects.h @@ -129,6 +129,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32G0/objects.h b/targets/TARGET_STM/TARGET_STM32G0/objects.h index 3f9ecf736c..638d4e8725 100644 --- a/targets/TARGET_STM/TARGET_STM32G0/objects.h +++ b/targets/TARGET_STM/TARGET_STM32G0/objects.h @@ -112,6 +112,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32G4/objects.h b/targets/TARGET_STM/TARGET_STM32G4/objects.h index c548ad77e4..bb466ce224 100644 --- a/targets/TARGET_STM/TARGET_STM32G4/objects.h +++ b/targets/TARGET_STM/TARGET_STM32G4/objects.h @@ -111,6 +111,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32L0/objects.h b/targets/TARGET_STM/TARGET_STM32L0/objects.h index ca3b5b4221..642a202c18 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/objects.h @@ -114,6 +114,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32L1/objects.h b/targets/TARGET_STM/TARGET_STM32L1/objects.h index 9f5619ca87..91589c9a5b 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L1/objects.h @@ -110,6 +110,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32L4/objects.h b/targets/TARGET_STM/TARGET_STM32L4/objects.h index 164469160d..b5993913f7 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/objects.h @@ -110,6 +110,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32L5/objects.h b/targets/TARGET_STM/TARGET_STM32L5/objects.h index 195fcc2fda..5dbd6abb69 100644 --- a/targets/TARGET_STM/TARGET_STM32L5/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L5/objects.h @@ -118,6 +118,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32WB/objects.h b/targets/TARGET_STM/TARGET_STM32WB/objects.h index ee48fe55c8..ead49f7692 100644 --- a/targets/TARGET_STM/TARGET_STM32WB/objects.h +++ b/targets/TARGET_STM/TARGET_STM32WB/objects.h @@ -101,6 +101,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address; diff --git a/targets/TARGET_STM/TARGET_STM32WL/objects.h b/targets/TARGET_STM/TARGET_STM32WL/objects.h index 4116fec5ef..72270cd4c2 100644 --- a/targets/TARGET_STM/TARGET_STM32WL/objects.h +++ b/targets/TARGET_STM/TARGET_STM32WL/objects.h @@ -104,6 +104,9 @@ struct i2c_s { uint8_t slave; volatile uint8_t pending_slave_tx_master_rx; volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint8_t slave_rx_buffer_size; + volatile uint8_t slave_rx_count; #endif #if DEVICE_I2C_ASYNCH uint32_t address;