ST HAL I2C generating wrong address.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-02-12 6:42 AM
Hello,
I've been working with ST HAL libraries for an STM32F030R8T6, using the NUCLEO board, and I'm having some problems with the I2C API. Probably it's a configuration issue but for the love of me, I can't find it. The problem: I call the functionHAL_I2C_Master_Transmit_XX
with address 0x3E. I attach a logic analyzer to the output to check the lines, and the address does not match. The address I see on the line is 0x1F. My main test code is the following. (Just to reproduce this situation) It is a direct copy from the NUCLEO examples. I skip over theSystemClock_Config
andMspInit
, since I can see data on the lines (I2C is sending data correcly) and they don't provide information for my current problem.
#define I2C_ADDRESS 0x3E
#define I2C_TIMING 0x00A51314
uint8_t bTransferRequest = 0;
//(other stuff)
int
main(
void
)
{
HAL_Init();
/* Configure the system clock to 48 MHz */
SystemClock_Config();
/*##-1- Configure the I2C peripheral ######################################*/
I2cHandle.Instance = I2C1;
I2cHandle.Init.Timing = I2C_TIMING;
I2cHandle.Init.OwnAddress1 = I2C_ADDRESS;
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
I2cHandle.Init.OwnAddress2 = 0xFF;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if
(HAL_I2C_Init(&I2cHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Enable the Analog I2C Filter */
HAL_I2CEx_ConfigAnalogFilter(&I2cHandle,I2C_ANALOGFILTER_ENABLE);
while
(1){
HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)I2C_ADDRESS, (uint8_t*)&bTransferRequest, 1, 1000);
HAL_Delay(1000);
}
return
0;
}
This code, when examining the output with the logic analyzer, generates the following SDA/SCL sequence.
/*******************************************************************************
* @file stm32f0xx_hal_i2c.c
* @author MCD Application Team
* @version V1.3.0
* @date 26-June-2015
******************************************************************************/
//(etc)
static
void
I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request){
//(etc)
/* update tmpreg */
tmpreg |= (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << 16 ) & I2C_CR2_NBYTES) | \
(uint32_t)Mode | (uint32_t)Request);
/* update CR2 register */
hi2c->Instance->CR2 = tmpreg;
And from the
http://www.st.com/web/en/resource/technical/document/reference_manual/DM000319pdf
, section 7.2, Control Register 2 (I2C_CR2):Bits 9:8 SADD[9:8]: Slave address bit 9:8 (master mode)
This bit are don’t care
Bits 7:1 SADD[7:1]: Slave address bit 7:1 (master mode)
These bits should be written with the 7-bit slave address to be sent
Bit 0 SADD0: Slave address bit 0 (master mode)
This bit is don’t care
I understand that on 7 bit address mode, the CR2 bits used to generate the address are SADD[7:1] neglecting the value of SADD0. But the ST HAL driver seems to write the value directly (with no shifting at all),
hence the ''transformation'' from 0x3E to 0x1F:
I2C_CR2[7:0] = 0x3E
I2C_CR2[7:1] = 0x1F
This would be fine for 10 bit addresses, but I'm having trouble with 7 bit.
I tested using an I2C temperature sensor (address 0x40). And I can't read anything at all using 0x40, but everything is fine and dandy when using 0x
Could somebody please point me to any configuration flag that I may have missed?
Salut!
#i2c #hal #cubemx #stm32
- Labels:
-
I2C
-
STM32Cube MCU Packages
-
STM32CubeMX
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-02-12 7:09 AM
ST, like many others, represent the 7-bit address as the high order 7-bits exactly as they appear on the bus, and the low order R/W bit is determined depending on the nature of the interaction. In these types of systems the address becomes (DATASHEET_ADDR << 1)
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-02-15 1:00 AM
Thanks for your response.
I was already shifting the address, but was not sure if this was the ''correct'' behaviour. Salut!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-02-15 2:20 AM
No problem, you just have to watch the system and device data sheets and implementations very carefully. People have represented the 7-bit address in all manner of ways over the decades, so I always double check what the data sheet says, and what the timing diagram illustrates, and then contrast that with how it is handled in the software side driver stack.
Up vote any posts that you find helpful, it shows what's working..
