[SOLVED] I²C - [STM32CubeL4][1.13.0][stm32l4xx_hal_i2c] Wrong RD_WRN value
I may be mistaken but It appears that the HAL is not computing the correct value for the RD_RWN bit as defined line 6319 of the file stm32l4xx_hal_i2c.c:
/**
* @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
* @param hi2c I2C handle.
* @param DevAddress Specifies the slave address to be programmed.
* @param Size Specifies the number of bytes to be programmed.
* This parameter must be a value between 0 and 255.
* @param Mode New state of the I2C START condition generation.
* This parameter can be one of the following values:
* @arg @ref I2C_RELOAD_MODE Enable Reload mode .
* @arg @ref I2C_AUTOEND_MODE Enable Automatic end mode.
* @arg @ref I2C_SOFTEND_MODE Enable Software end mode.
* @param Request New state of the I2C START condition generation.
* This parameter can be one of the following values:
* @arg @ref I2C_NO_STARTSTOP Don't Generate stop and start condition.
* @arg @ref I2C_GENERATE_STOP Generate stop condition (Size should be set to 0).
* @arg @ref I2C_GENERATE_START_READ Generate Restart for read request.
* @arg @ref I2C_GENERATE_START_WRITE Generate Restart for write request.
* @retval None
*/
static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
assert_param(IS_TRANSFER_MODE(Mode));
assert_param(IS_TRANSFER_REQUEST(Request));
/* update CR2 register */
MODIFY_REG(hi2c->Instance->CR2, ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP)), \
(uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request));
}where:
(I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos)))seems wrong as it shifts 21 bits to the rights the Request value which may be I2C_GENERATE_START_READ or I2C_GENERATE_START_WRITE as defined in stm32l4xx_hal_i2c.h.
Or I2C_GENERATE_START_READ is already "ORed" with I2C_CR2_RD_WRN by definition. So the function I2C_TransferConfig should be changed to:
static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
assert_param(IS_TRANSFER_MODE(Mode));
assert_param(IS_TRANSFER_REQUEST(Request));
/* update CR2 register */
MODIFY_REG(hi2c->Instance->CR2, ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | (I2C_CR2_RD_WRN & Request) | I2C_CR2_START | I2C_CR2_STOP)), \
(uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request));
}where:
(I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos)))is replaced with:
(I2C_CR2_RD_WRN & Request)I am not 100% sure so any feedback about this is highly appreciated.
