2017-10-18 05:50 AM
Hi
I'm using I2C1 periphery of a STM32F205 device in master mode. The firmware is based on the
HAL
V1.2.1 driver with interrupt approach
. Three slaves are attached to the bus and 7bit address mode is used.I'm able to communicate with two slave devices but the communication with the third device fails. I following sequence could be observed within the 'HAL_I2C_EV_IRQHandler()' handler:
Valid sequence:
1. SB bit was set (Start send)
2. ADDR bit was set (Slave address send)
Void seqence:
1. SB bit was set
(Start send)
2. ADD10 bit was set
(First byte of 10bit address send) -> Should be ADDR
The communication fails because the ADD10 bit of the I2C_SR1 got set instead of the ADDR bit. 7bit mode is still configured I2C_OAR1= 0x4000.
The obvious difference within the code is the slave address which is 0xF0 for the device which fails and 0xEC and 0x90 for the other ones.
Has someone any idea why the I2C master rise a ADD10 interrupt instead of the ADDR? The only difference within the code is the slave address which is 0xF0 for the device which fails and 0xEC and 0x90 for the other ones.
The I2C initialization code generated by cube is:
/* I2C1 init function */
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 400000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
Start of transfer is:// Send the byte stream by ISR
if ( HAL_OK == HAL_I2C_Master_Transmit_IT( ptrToHandle, ptrToStreamTx->addr, ptrToStreamTx->ptrToData, ptrToStreamTx->size ) ) {
Solved! Go to Solution.
2017-10-19 05:34 PM
Hello Raphael!
You are right about the version. Is the newest. Had in my mind
Firmware
v1.6.About the 10 bit address behaviour, when initialize the I2c with I2C_ADDRESSINGMODE_10BIT the first byte sent is the Header 0b11110XXy and the second is the LO address byte 0bXXXXXXXX.
Take a look inside I2C_Master_SB function (called when the SB flag is set ) for the first byte and inside I2C_Master_ADD10 for the second byte.
My conclusion is that for your case , is enough to change the 'Init.AddressingMode' before you transmit the 10-bit address and restore it to 7 bits mode after
finish the transaction
. I2C_OAR1 concerns slave mode only.ptrToHandle->Init.AddressingMode = I2C_ADDRESSINGMODE_10BIT;
HAL_I2C_Master_Transmit_IT(.... 10bit addr); // func for transmit.
// after finish transaction and before you call the next transmit_IT function change the addressing mode again.// .....
ptrToHandle->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;//....Regardsvf2017-10-18 07:40 AM
Hi
The observed behavior could be explained as follow:
First the slave address of 0xF0 is in the range of the reserved pattern for the 10bit device addressing '11110xx'. In master mode the I2C periphery will automatically switch to 10bit mode if the 10bit pattern will be detected independent of the
I2C_SR1 settings.
This results in the rising of the ADD10 interrupt.Second the interrupt approach of the
HAL
V1.2.1 I2C driver
is buggy. 10bit mode is not properly implemented. The result is, that the low byte of the 16bit slave address will be send twice and the content of the high byte will not be transferred.2017-10-18 07:57 AM
Hello!
HAL
V1.2.1
is an old version.Sugest to upgrade to latest version.
I don't use F2 family but the approach for Device address lenght handling, is better in latest version than 1.2.
By the way the 0xF0 is a 10bit address.
Regards
vf
2017-10-18 08:32 AM
where do I find, at least some, documentation for the stmF0 I2C library.
sorry about butting in here, but trying to make a new thread states 'add a title' with no place to add the title
2017-10-19 12:36 AM
Dear Vangelis
Thanks for the feedback.
The HAL file of the I2C driver 'stm32f2xx_hal_i2c.c' has the verison V1.2.1. and date '14-April-2017'. The file is part of the 'STM32Cube_FW_F2_V1.6.0' package installed by Cube. This is the latest package I could find with Cube. Are you sure there is a newer one and where do I get it?
Thanks Raphael
2017-10-19 05:34 PM
Hello Raphael!
You are right about the version. Is the newest. Had in my mind
Firmware
v1.6.About the 10 bit address behaviour, when initialize the I2c with I2C_ADDRESSINGMODE_10BIT the first byte sent is the Header 0b11110XXy and the second is the LO address byte 0bXXXXXXXX.
Take a look inside I2C_Master_SB function (called when the SB flag is set ) for the first byte and inside I2C_Master_ADD10 for the second byte.
My conclusion is that for your case , is enough to change the 'Init.AddressingMode' before you transmit the 10-bit address and restore it to 7 bits mode after
finish the transaction
. I2C_OAR1 concerns slave mode only.ptrToHandle->Init.AddressingMode = I2C_ADDRESSINGMODE_10BIT;
HAL_I2C_Master_Transmit_IT(.... 10bit addr); // func for transmit.
// after finish transaction and before you call the next transmit_IT function change the addressing mode again.// .....
ptrToHandle->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;//....Regardsvf2017-10-20 01:32 AM
Dear Vangelis
Your conclusion is correct, thanks. Interrupt approach with 10bit master mode work's in the actual HAL implementation.
Fortunately I only has to write to the 7bit slave device with a slave address equal to the 10bit header. As a workaround I could configure the I2C for 10bit addressing (This solves the issue with sending the low byte of the slave address twice). Mask the first data byte into the slave address low byte and start a transfer.
Regards Raphael