Skip to main content
Associate II
June 17, 2025
Solved

I2C slave register address not updating using HAL_I2C_Mem_Read function

  • June 17, 2025
  • 2 replies
  • 797 views

Hello,

 

I am new on the embedded subject, and I need some help.

I want to practice I2C communication, so I connected Nucleo-L4P5ZG (master), and MAX6604EVKIT (slave), the general goal is to read registers and send the result via UART.

I used the STM32cubeMX to generate the initial code.

I used the HAL function " HAL_I2C_Mem_Read"  to read register in address 0x6.

Build process went without errors.

During debug, when looking at the scope, it seems that the MCU don't change the register address to 0x6, and it is stuck on 0x0.

The slave address is correct, and I receive ACK (0 logic).

I am attaching the main.c.

Do you know what seems to be the problem?

Thanks

Shay

 

Best answer by TDK

> I2C_MEMADD_SIZE_16BIT

After the address, it sends 0x00 and then 0x06. That is exactly what it should send for the 16-bit address of 0x06.

Since MAX6604 has 8-bit addresses, not 16, you should use I2C_MEMADD_SIZE_8BIT.

2 replies

TDK
Super User
June 17, 2025

Show the code and show the scope trace. The HAL_I2C_Mem_Read function works as intended, has to be another explanation.

"If you feel a post has answered your question, please click ""Accept as Solution""."
ShayAuthor
Associate II
June 19, 2025

Hi TDK,

Thanks for responding.

 

The scope images are attached.

This is the code:

 
void ReadFromI2C()
{
 uint16_t Devaddr = (0x18 << 1) | 0x01;
	uint16_t MemAddress = 0x6; // Memory address to read from
	uint8_t pData[2]; // Buffer to store the read data
	uint16_t Size=2;
	uint32_t Timeout = 10000; // Timeout duration in ms
	HAL_StatusTypeDef status;

	status=(HAL_I2C_Mem_Read(&hi2c1, Devaddr, MemAddress, I2C_MEMADD_SIZE_16BIT, pData, Size, Timeout) != HAL_OK);


 // Check for success
 if (status == HAL_OK) {
 	// printf("Device is ready for communication.\n");
 // Successfully read data, process read_buf as needed
 } else {
 	// printf("Device is not ready or not responding.\n");
 // Handle error
 }
 }

Thanks

Karl Yamashita
Principal
June 20, 2025

Assuming I2C1.jpg is the start of the data, the first write to the slave address 0x18 should not have the read bit set. But you can see in the image, the 8th bit there is glitch where the data is high, but it should be a low since it's a write. \

It might have to do with how your setting up the slave address

uint16_t Devaddr = (0x18 << 1) | 0x01;

// instead, do it like this. The HAL driver will take care of the read/write bit automatically.
uint16_t Devaddr = (0x18 << 1);

 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
TDK
TDKBest answer
Super User
June 19, 2025

> I2C_MEMADD_SIZE_16BIT

After the address, it sends 0x00 and then 0x06. That is exactly what it should send for the 16-bit address of 0x06.

Since MAX6604 has 8-bit addresses, not 16, you should use I2C_MEMADD_SIZE_8BIT.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Bob S
Super User
June 19, 2025

This does not affect the actual data on the bus, but you don't need to, and should not, set the LSB of the device address.  The STM32 HAL code expects the 7-bit I2C address in the upper 7 bits with the LSB=0. The HAL code will set/clear this bit as needed for read and write operations.