Skip to main content
Dick Lin
Senior
August 16, 2018
Question

I2C HAL_I2C_Mem_Read ( ) failed

  • August 16, 2018
  • 15 replies
  • 4830 views

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;

  }

    This topic has been closed for replies.

    15 replies

    T J
    Senior III
    August 17, 2018

    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
    Dick LinAuthor
    Senior
    August 17, 2018

    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
    Dick LinAuthor
    Senior
    August 17, 2018

    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
    Senior III
    August 17, 2018

    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
    Dick LinAuthor
    Senior
    August 17, 2018

    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
    Senior III
    August 17, 2018

    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
    Dick LinAuthor
    Senior
    August 17, 2018

    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
    Dick LinAuthor
    Senior
    August 17, 2018

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

    T J
    Senior III
    August 17, 2018

    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

    T J
    Senior III
    August 17, 2018

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

    that's incorrect.

    read is 0b10100001

    dbo
    Associate II
    January 17, 2019

    0690X000006D8D0QAK.jpgHi,

    I'm using HAL_I2c_Mem_Read(), too.

    And may I ask if STM32's I2C can generate wave like the following picture. I have tryed Mem_read() and any other function in i2c.c , but the bit following device addres is "0",which means "write" in I2c.

    May you help me out, thanks.

    Tesla DeLorean
    Guru
    January 17, 2019

    Yes, that doesn't look like the usual I2C method, which is to have a WRITE with the Register Address, and then a READ which pulls the data.

    Probably going to need to bit-bang the frame here.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..