This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

I2C Acknowledge Polling for 24LC1025

Other Parts Discussed in Thread: TM4C123FH6PM

Hello,

I am trying to implement a function for acknowledge polling after an EEPROM write or read, in order to avoid using a delay.

Here is the code i am trying to use after some searching:

bool EEPROM_isReady(void)
{
        ROM_I2CMasterSlaveAddrSet((I2C0), EEPROM_ADDRESS, false);  // true = read

        // Try to perform a write operation
        ROM_I2CMasterDataPut(I2C0, 0x00);
        ROM_I2CMasterControl(I2C0, I2C_MASTER_CMD_SINGLE_SEND);
        while (ROM_I2CMasterBusy(I2C0));
        // If there is an error, it means the EEPROM is still busy
        return (I2C_MASTER_ERR_NONE == ROM_I2CMasterErr(I2C0)); 
}

But this function returns always false.

Is there something wrong in that code? or is there any other way to implement the acknowledge polling? 

Thanks in advance if you have any suggestion.

  • Unstated is your MCU - that's required - is it not?
    There are substantial differences between (basic) TM4C123 and (more advanced) TM4C129 - especially impacting I2C operation...

    Notable is your revealing of the EEProm - while the MCU is unmentioned!  

    And - that EEProm is complex - "KISS" argues for your use of a far smaller, more basic EEProm first - which most always, "Speeds, Eases & Enhances" your success...

  • Sorry i forgot to mention. The microcontroller i am using is the TM4C123FH6PM.

    After every write or read operation i inserted the function as:

    while (!EEPROM_isReady());

    But it never comes out of that cycle.

    Thank you for the reply.

  • Thank you - firm/I work w/that family MCU.
    I travel to client site now - will be back to you in several hours if vendor does not resolve.

    Still - a smaller, simpler EEProm provides an effective "waypoint" on your journey. (sailing "around the world" as "first go" makes (not) much sense!)
  • Unfortunately, the project was designed and made with this EEPROM already, the hardware is a little bit complex and we already have a lot of prototypes mounted, so changing the EEPROM by now should be our last option.

    I can simply add a delay after every write and read cycle, I just want the code to be more efficient implementing the acknowledge polling.
  • You can simply "clip-in" a simple EEProm - that is done by (large) firms (w/whom we engage) "all the time." (open the connections to the "overly-challenging" EEProm.

    Have you installed pull-up Rs (4K7-10K) on each of the I2C lines? I must go now...
  • Yes, pull-up resistors are installed in both I2C lines. And the code works well writing and reading normally, so i don't think the problem is on the hardware side.
  • Quickly - cannot you (temporarily) monitor SDA by tieing it to an unused GPIO? (in addition to the normal SDA termination) Via this means - or use of a storage scope - you can monitor "ACK" behavior.
  • Akira Mitsui said:
    is there any other way to implement the acknowledge polling? 

    Believe that your "scope monitoring" of SDA and/or (temporary) routing of SDA to an unused GPIO input will better enable your success.   You need to confirm that "ACK" (or "NAK") is being generated - and armed w/that knowledge - you'll be better equipped to succeed w/your "wait eliminating" function...

  • Akira,

    I would agree with cb1 that it would be beneficial for you to monitor SDA to see what is going on with the signal causing the I2C to never show not busy. From you code, it appears you are sending a byte (0x00) to the slave and then expecting a simple ACK/NACK in return or is there data expected to be returned? What does the 24LC1025 device datasheet state the expected response from the device to be?
  • Hello to all.

    Sorry i was off these days. Thank you for all the help.

    Yes, i am sending a byte to the slave and then see if there was an error, if there is not, the function returns true and the code continues.

    Today i returned in trying to fix this problem, i started debugging and i have found that i am getting and arbitration lost error (I2C_MASTER_ERR_ARB_LOST). Why can this be happening? I wrote the following code when i get this error in order to restart I2C, but the problem continues:

    ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);          // Reset peripheral
    // Init I2C master block
    ROM_I2CMasterInitExpClk(I2C0, ROM_SysCtlClockGet(), I2C_Speed);

    Any information will be appreciated, thanks in advance,.

  • I forgot to say that after i insert the restart I2C function, i am getting both I2C_MASTER_ERR_ADDR_ACK and I2C_MASTER_ERR_DATA_ACK errors.
  • Hello Akira,

    Can you please share the configuration of the IO's for the I2C Module?

    Regards
    Amit
  • Hello Amit. This is the configuration and initialization of the I2C module:

    void I2C_init(bool I2C_Speed)
    {
            ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);     // Enable peripherals
            ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
            
            ROM_GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); // Pin type configuration
            ROM_GPIOPinTypeI2C   (GPIO_PORTB_BASE, GPIO_PIN_3); // 
            ROM_GPIOPinConfigure (GPIO_PB2_I2C0SCL);            // PB2 (clock)
            ROM_GPIOPinConfigure (GPIO_PB3_I2C0SDA);            // PB3 (data)
            
            // Set PB2 and PB3 as 2mA output drive strength
            // Set PB2 as push-pull pin
            // Set PB3 as open-drain weak pull-up
            ROM_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
            ROM_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD );
            
            // Init I2C master block
            ROM_I2CMasterInitExpClk(I2C0, ROM_SysCtlClockGet(), I2C_Speed);
            
            ROM_I2CMasterIntEnable(I2C0);                  // Enable I2C interrupt     
    }

    Thanks for the quick reply.

  • Hello Akira,

    Can you please remove the lines

    // Set PB2 and PB3 as 2mA output drive strength
    // Set PB2 as push-pull pin
    // Set PB3 as open-drain weak pull-up
    ROM_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
    ROM_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD );

    Regards
    Amit
  • Ok. Thank you Amit, I removed the lines, now I will wait in order to see it the problem occurs again.
    Regards.
  • Hello Akira,

    Make sure that you have a scope handy to see what is being transacted on the I2C SCL and SDA lines.

    Regards
    Amit