Skip to main content
Senior
June 9, 2026
Solved

I2C Problems With KTD2037 Using HAL

  • June 9, 2026
  • 4 replies
  • 29 views

I have a custom board with G491 and an LED driver (Kinetic KTD2037). MCU is the I2C master. Any attempt to read a register using HAL from the KTD2037 fails, ErrorCode = 0x2 (arb lost). Register writes are OK. I can read/write other devices on the same bus OK.

 

The KTD2037 datasheet has this for an I2C register read:

This doesn’t seem consistent with HAL_I2C_Mem_Read() or HAL_I2C_Master_Receive(). 

On a scope HAL_I2C_Mem_Read() results in

  S, 7-bit addr, write, ack, reg addr, ack, Sr, 7-bit addr, read, ack, 0xFF, nack

I try setting the internal register pointer (it may not have one) using HAL_I2C_Master_Transmit(), which works OK. Then I follow it with HAL_I2C_Master_Receive() resulting in

  S, 7-bit addr, read, ack, 0xFF, nack

It looks like the master says arbitration lost because of unexpected nack from the KtTD037.

The KTD2037 datasheet does not mention I2C repeat start.

Any way to read this device without writing my own I2C driver?

Best answer by TDK

> The KTD2037 datasheet has this for an I2C register read:

This is consistent with a HAL_I2C_Master_Receive call to read 2 bytes. The first byte will be “Register Address” and the second will be “Data”.

HAL_I2C_Mem_Read is not meant for this.

 

If you want to write an address, then read it, you can either do:

HAL_I2C_Mem_Read with a single byte write and a two byte read.

or

HAL_I2C_Master_Transmit with a single byte write plus a HAL_I2C_Mem_Read with a two byte read. These will be separate transactions unlike HAL_I2C_Mem_Read where it will be a repeated start condition.

4 replies

TDK
TDKBest answer
June 9, 2026

> The KTD2037 datasheet has this for an I2C register read:

This is consistent with a HAL_I2C_Master_Receive call to read 2 bytes. The first byte will be “Register Address” and the second will be “Data”.

HAL_I2C_Mem_Read is not meant for this.

 

If you want to write an address, then read it, you can either do:

HAL_I2C_Mem_Read with a single byte write and a two byte read.

or

HAL_I2C_Master_Transmit with a single byte write plus a HAL_I2C_Mem_Read with a two byte read. These will be separate transactions unlike HAL_I2C_Mem_Read where it will be a repeated start condition.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Karl Yamashita
Lead III
June 10, 2026

The KTD2037 is not doing the NACK. It’s the STM32 that does the NACK during READs after it’s done reading the correct number of bytes to notify the slave to stop sending data. That is normal behavior. 

 

When you get HAL_BUSY = 0x02 when calling HAL_I2C_Mem_Read, could mean a number of scenarios. Try debugging and put a breakpoint in HAL_I2C_Mem_Read and see which of the 2 HAL_BUSY it returns from. Then you can narrow it down further. Also check the SR1 and SR2 registers to see which bits are set, if any.

  • if (hi2c->State == HAL_I2C_STATE_READY) will return HAL_BUSY if not equal.
  • Will return HAL_BUSY if it times out.  

 

The datasheet read command doesn’t look correct. But i could be wrong with this particular part.

When reading from a register, you typically want to WRITE the register value, then READ with the device address preceding the data like below. 

 

 

 

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
mccabehmAuthor
Senior
June 10, 2026

By ErrorCode = 0x2, I mean hi2c2.ErrorCode, not return from HAL_I2C_Mem_Read(). hi2c2.ErrorCode = 0x2 => arbitration lost.

 

 

 

mccabehmAuthor
Senior
June 10, 2026

“HAL_I2C_Mem_Read with a single byte write and a two byte read” works OK.