2024-12-18 03:56 AM - edited 2024-12-18 03:57 AM
I have a custom PCB with a STM32U575 for which I generate code using STM32CubeMX.
I am now trying to get I2C to work. Both the I2C1 and I2C2 channels each have one I2C slave. But for both I get the same problem: the slaves do not acknowledge the master messages. The I2C transmission then returns with an error.
For now I am testing with very basic code:
const uint8_t source[1] = {0x00};
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, 0x64, source, 1, 1000);
uint32_t errorCode = HAL_I2C_GetError(&hi2c1);
Here status is HAL_ERROR and errorCode is HAL_I2C_ERROR_AF.
I put a logic analyzer on the SDA and SCL channels and I can confirm the slave really doesn't send the expected ACK:
In the yellow region the SDA should be pulled low.
The CubeMX config:
Both are set to 'open drain' as they should be.
Just to try I made a little scan over all 128 I2C addresses, but I don't get an acknowledgement anywhere. I've also tried about all possible I2C configurations, but to no avail.
It's odd both slaves have the same effects, on different channels.
Thanks for any advice!
Solved! Go to Solution.
2024-12-18 04:50 AM - edited 2024-12-18 04:51 AM
I figured it out and it was right in front of me. I had forgotten to bit-shift the device address by 1. And even my address scan failed here because I only scanned up to 0x7F, not up to 0xFF.
So I can now read the slave status with:
const uint8_t devAddr = 0x64 << 1; // CubeMX uses only the 7 most-significant bits as address
const uint8_t regStatus = 0x00;
state = HAL_I2C_Master_Transmit(&hi2c1, devAddr, ®Status, 1, 1000);
uint8_t status;
HAL_I2C_Master_Receive(&hi2c1, devAddr, &status, 1, 1000);
I feel silly because the docblock clearly states this:
I figured this out because I was looking at the logic analyzer during the address scan and I saw each address scroll by twice (e.g. 0x00, 0x00, 0x01, 0x01, etc.) instead of incrementing each time.
2024-12-18 04:14 AM
@Robert_149494 wrote:I have a custom PCB !
Post the schematic.
@Robert_149494 wrote:Both the I2C1 and I2C2 channels each have one I2C slave. But for both I get the same problem: the slaves do not acknowledge the master messages.!
What are the slaves? Are you sure you have them correctly enabled, configured, etc ?
Before making a custom PCB, did you test this on a dev board?
That way you should easily be able to test that you have correct pullup values, correct addresses, etc - without any doubts about untested hardware issues ...
2024-12-18 04:50 AM
Note that 7-bit slave address should be left-shifted one bit. Could be it.
Possibly the slave chips are not powered or are miswired.
Get HAL_I2C_IsDeviceReady to return HAL_OK before you do anything else with HAL_I2C.
You've confirmed the SDA/SCL signal exist, which is good. Not a code issue in that case.
2024-12-18 04:50 AM - edited 2024-12-18 04:51 AM
I figured it out and it was right in front of me. I had forgotten to bit-shift the device address by 1. And even my address scan failed here because I only scanned up to 0x7F, not up to 0xFF.
So I can now read the slave status with:
const uint8_t devAddr = 0x64 << 1; // CubeMX uses only the 7 most-significant bits as address
const uint8_t regStatus = 0x00;
state = HAL_I2C_Master_Transmit(&hi2c1, devAddr, ®Status, 1, 1000);
uint8_t status;
HAL_I2C_Master_Receive(&hi2c1, devAddr, &status, 1, 1000);
I feel silly because the docblock clearly states this:
I figured this out because I was looking at the logic analyzer during the address scan and I saw each address scroll by twice (e.g. 0x00, 0x00, 0x01, 0x01, etc.) instead of incrementing each time.
2024-12-18 04:55 AM
Jinx. Yeah, that was it.