cancel
Showing results for 
Search instead for 
Did you mean: 

I2C HAL_I2C_Mem_Read ( ) failed

Dick Lin
Senior

Hi,

I am working on I2C read EEPROM. The HAL function failed due to the I2C_FLAG_BUSY is always SET.

Is there anything I am missing in init code?

Thx

  if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)

  {

   return HAL_TIMEOUT;

  }

18 REPLIES 18
T J
Lead

this code works:

note the address is shifted up 1 bit...

#define MCP4728_DacAddress 0x60 << 1

void write4Dacs(void) {
    char buf[16];
 
    struct DacIIC MCP4728IIC;   
    HAL_StatusTypeDef IIC_Response;
  
    //    Dac_Value  = (4096 * 1) / 5;      // 1V
    
    //Channel 0
    MCP4728IIC.DacTxBuffer[0] =  (Dac0_Value & 0x0f00) >> 8;
    MCP4728IIC.DacTxBuffer[1] =   Dac0_Value & 0x00ff;
 
    //Channel 1
    Dac1_Value  = Dac0_Value + (4096 * 1) / 5;      // 1V
    MCP4728IIC.DacTxBuffer[2] =  (Dac1_Value & 0x0f00) >> 8;
    MCP4728IIC.DacTxBuffer[3] =   Dac1_Value & 0x00ff;
 
    //Channel 2
    Dac2_Value  = Dac1_Value + (4096 * 1) / 5;      // 2V
    MCP4728IIC.DacTxBuffer[4] =  (Dac2_Value & 0x0f00) >> 8;
    MCP4728IIC.DacTxBuffer[5] =   Dac2_Value & 0x00ff;
 
    //Channel 3
    Dac3_Value  = Dac2_Value + (4096 * 1) / 5;      // 3V
    MCP4728IIC.DacTxBuffer[6] =  (Dac3_Value & 0x0f00) >> 8;
    MCP4728IIC.DacTxBuffer[7] =   Dac3_Value & 0x00ff;
 
    //DAC_IIC.write(DAC_ADDR + (Dac_Address << 1), buf, 8);   
    IIC_Response = HAL_I2C_Master_Transmit(&hi2c1, MCP4728_DacAddress, &MCP4728IIC.DacTxBuffer[0], 8, 10);
 
    
}

Dick Lin
Senior

The issue is I2C_FLAG_BUSY is always SET. That's why this function bailed out after timeout.

We are using 24AA02E48 to get EUI-48. Thx

static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)

{

 while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)

Dick Lin
Senior

I checked the I2C registers. ISR register value is 0x8009 (1000000000001001) which means bit 15 is set in HAL_I2C_Mem_Read() function.

I also check the flag before call read. Not sure how to turn it off.

uint32_t flag = __HAL_I2C_GET_FLAG(m_i2c, I2C_FLAG_BUSY);

Bit 15 BUSY: Bus busy

This flag indicates that a communication is in progress on the bus. It is set by hardware when a

START condition is detected. It is cleared by hardware when a STOP condition is detected, or

when PE=0.

T J
Lead

Sorry to catchup, which part ?

what address are you using ?

on initisation the errent flag is set or not ?

try power off and then check the flag it should be clear.

then check the DAC code I sent... I don't check any flags, it just works.

which part ? and what address is it ?

and show us the first line of transmit.

Dick Lin
Senior

I am using STM32L4A6VG MCU connecting I2C 2 to Microchip 24AA02E48 EEPROM (2K I2C Serial EEPROMs with EUI-48™ or EUI-64™ Node Identity) for EUI-48 ID.

http://ww1.microchip.com/downloads/en/DeviceDoc/20002124G.pdf

There is no transition happened at all since all of checking before TX/RX. I am able to DISABLE/ENABLE I2C to make the first BUSY flag go away. Now I am seeing this TXIS flag is not set. Thx

 /* Wait until TXIS flag is set */

 if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)

T J
Lead

how are the pins A0 A1 A2 set ? 0,0,0 ?

thats 0xA0 for Write and 0xA1 for Read,

are you using just one device on the IIC bus ?

in my code there is no initialisation, it just works...

Dick Lin
Senior

Thanks for the input. Just figured out the way our layers of driver works should OR 0x01 before calling 24AA02E48 driver. Thanks a lot.

m_i2c->read_from_address(0b10100000, 0xFA, 1, in_data, in_len);

Dick Lin
Senior

I still have the same error with the READ address modified. Thx

T J
Lead

I guess you are using blocking code, and you are read/nested read/nested read/stopped/// I guess

can you try this ?

POWER OFF for 5 seconds

READ ONCE only.

wait 1 second

READ again