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.

TMS320F28386D: RTC example

Part Number: TMS320F28386D

Hello,

I'm testing the same example used here: https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1306409/tms320f280025c-ds3231n

so I'm trying to read from RTC but I'm unable to read the data:

I'm using different C2000microcontroller (TMS320F28386D), RTC (ISL12022M) and from Datasheet I have not clear what is the address to use: I supposed that the correct address is 0x6F:

Device Addressing

Following a start condition, the master must output a Slave Address Byte. The 7 MSBs are the device identifiers. These bits are “1101111” for the RTC registers and “1010111” for the User SRAM.

The last bit of the Slave Address Byte defines a read or write operation to be performed. When this R/W bit is a “1”, a read operation is selected. A “0” selects a write operation

But I'm not clear how to set the Read/Write bit in the code. In my case, I have to set 1 for read operation, but where have I to set this value?

//#############################################################################
//
// FILE:   i2cLib_FIFO_polling.c
//
// TITLE:  C28x-I2C Library source file for FIFO using polling
//! <h1> C28x-I2C Library source file for FIFO using polling </h1>
//
//#############################################################################
//#############################################################################
//
//
// $Copyright:
// Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

#include "i2cLib_FIFO_polling.h"

uint16_t I2CBusScan(uint32_t base, uint16_t *pAvailableI2C_targets)
{
    uint16_t probeTargetAddress, i;

    //Disable interrupts on Stop condition, NACK and arbitration lost condition
    I2C_disableInterrupt(base, (I2C_INT_ADDR_TARGET|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));

    i = 0;
    for(probeTargetAddress=1;probeTargetAddress<=MAX_10_BIT_ADDRESS;probeTargetAddress++)
    {
        //Check I2C bus status
        status = checkBusStatus(base);
        if(status)
        {
           ESTOP0;
           return status;
        }

        I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE | I2C_REPEAT_MODE));

        //Enable 10-bit addressing if probeTargetAddress is greater than 127U
        if(probeTargetAddress > MAX_7_BIT_ADDRESS)
        {
            //10-bit addressing
            I2C_setAddressMode(base, I2C_ADDR_MODE_10BITS);
        }

        // Setup target address
        I2C_setTargetAddress(base, probeTargetAddress);


        I2C_sendStartCondition(base);

        //Wait for the target address to be transmitted
        while(!(I2C_getStatus(base) & I2C_STS_REG_ACCESS_RDY));

        //Generate STOP condition
        I2C_sendStopCondition(base);

        //Wait for the I2CMDR.STP to be cleared
        while(I2C_getStopConditionStatus(base));

        //Wait for the Bus busy bit to be cleared
        while(I2C_isBusBusy(base));

        uint16_t I2CStatus = I2C_getStatus(base);

        //If target address is acknowledged, store target address
        //in pAvailableI2C_targets
        if(!(I2CStatus & I2C_STS_NO_ACK))
        {
            pAvailableI2C_targets[i++] = probeTargetAddress;
        }
        //Clear NACK bit in I2CSTR
        I2C_clearStatus(base,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
    }

    I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE));
    I2C_setAddressMode(base, I2C_ADDR_MODE_7BITS); //7-bit addressing
    I2C_enableInterrupt(base, (I2C_INT_ADDR_TARGET|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
    return SUCCESS;
}

uint16_t I2C_TransmittargetAddress_ControlBytes(struct I2CHandle *I2C_Params)
{
    uint16_t status, attemptCount=1;

    uint32_t base = I2C_Params->base;

    status = 1;

    while(status & (attemptCount <= I2C_Params->NumOfAttempts))
    {
        status = checkBusStatus(base);
        attemptCount++;
        DEVICE_DELAY_US(I2C_Params->Delay_us);
    }

    if(status)
    {
        return status;
    }

    I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE|I2C_REPEAT_MODE));

    if((I2C_Params->TargetAddr) > MAX_7_BIT_ADDRESS)
    {
        //10-bit addressing
        I2C_setAddressMode(base, I2C_ADDR_MODE_10BITS);
    }

    // Setup target address
    I2C_setTargetAddress(base, I2C_Params->TargetAddr);


    int16_t  i;
    uint32_t temp = *(I2C_Params->pControlAddr);

    for(i=I2C_Params->NumOfAddrBytes-1;i>=0;i--)
    {
        I2C_putData(base, (temp >> (i*8U)) & 0xFF);
    }

    I2C_sendStartCondition(base);

    DEVICE_DELAY_US(150U);

    status = handleNACK(base);
    if(status)
    {
      if(attemptCount <= (I2C_Params->NumOfAttempts))
      {
          attemptCount++;
          I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE));
          I2C_sendStartCondition(base);
          DEVICE_DELAY_US(I2C_Params->Delay_us);
      }
      else
      {
          return status;
      }
	}

    attemptCount = 1;

    while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (I2C_Params->NumOfAddrBytes + 2U))
    {
       status = handleNACK(base);
       if(status)
       {
          return status;
       }
       attemptCount++;
       DEVICE_DELAY_US(I2C_Params->Delay_us);
    }

    return SUCCESS;
}

uint16_t I2C_ControllerTransmitter(struct I2CHandle *I2C_Params)
{
    uint16_t status, attemptCount;

    uint32_t base = I2C_Params->base;

    I2C_disableFIFO(base);
    I2C_enableFIFO(base);

    status = I2C_TransmittargetAddress_ControlBytes(I2C_Params);

    if(status)
    {
        return status;
    }

    I2C_setDataCount(base, (I2C_Params->NumOfAddrBytes + I2C_Params->NumOfDataBytes));

    I2C_setFIFOInterruptLevel(base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL);

    I2C_enableInterrupt(base, I2C_INT_TXFF);

    uint16_t numofSixteenByte  = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL;
    uint16_t remainingBytes    = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL;

    uint16_t i,count = 0,buff_pos=0;

    while(count < numofSixteenByte)
    {
        for(i=1;i<=I2C_FIFO_LEVEL;i++)
        {
            I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]);
        }

        attemptCount = 1;
        while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (I2C_FIFO_LEVEL + 2U))
        {
            status = handleNACK(base);
            if(status)
            {
              return status;
            }
            attemptCount++;
            DEVICE_DELAY_US(I2C_Params->Delay_us);
        }

        count++;
    }

    for (i=0; i < remainingBytes; i++)
    {
        I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]);
    }

    attemptCount = 1;
    while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (remainingBytes + 2U))
    {
        status = handleNACK(base);
        if(status)
        {
          return status;
        }
        attemptCount++;
        DEVICE_DELAY_US(I2C_Params->Delay_us);
    }

    I2C_sendStopCondition(base);

    attemptCount = 1;
    while(I2C_getStopConditionStatus(base) && attemptCount <= 3U)
    {
        DEVICE_DELAY_US(I2C_Params->Delay_us);
        attemptCount++;
    }

    return SUCCESS;
}

uint16_t I2C_ControllerReceiver(struct I2CHandle *I2C_Params)
{
    uint16_t status;
    uint16_t attemptCount;

    uint32_t base = I2C_Params->base;

    I2C_disableFIFO(base);
    I2C_enableFIFO(base);

    status = I2C_TransmittargetAddress_ControlBytes(I2C_Params);

    if(status)
    {
        return status;
    }

    uint16_t numofSixteenByte  = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL;
    uint16_t remainingBytes    = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL;

    I2C_setConfig(base, (I2C_CONTROLLER_RECEIVE_MODE|I2C_REPEAT_MODE));

    I2C_sendStartCondition(base);

    uint16_t i,count = 0,buff_pos=0;
    while(count < numofSixteenByte)
    {
        status = handleNACK(base);
        if(status)
        {
          return status;
        }

        count++;

        attemptCount = 1;
        while(!(I2C_getRxFIFOStatus(base) == I2C_FIFO_RXFULL) && attemptCount <= 9 * (I2C_FIFO_RXFULL + 2U))
        {
            DEVICE_DELAY_US(I2C_Params->Delay_us);
            attemptCount++;
        }

        for(i=0; i<I2C_FIFO_LEVEL; i++)
        {
            I2C_Params->pRX_MsgBuffer[buff_pos++] = I2C_getData(base);
        }
    }

    attemptCount = 1;
    while(!(I2C_getRxFIFOStatus(base) == remainingBytes) && attemptCount <= 9 * (remainingBytes + 2U))
    {
       DEVICE_DELAY_US(I2C_Params->Delay_us);
       attemptCount++;
    }

    I2C_sendStopCondition(base);

    for(i=0; i<remainingBytes; i++)
    {
        I2C_Params->pRX_MsgBuffer[buff_pos++] = I2C_getData(base);
    }

    status = handleNACK(base);
    if(status)
    {
      return status;
    }

    I2C_disableFIFO(base);

    attemptCount = 1;
    while(I2C_getStopConditionStatus(base) && attemptCount <= 3U);
    {
        DEVICE_DELAY_US(I2C_Params->Delay_us);
        attemptCount++;
    }

    return SUCCESS;

}


uint16_t checkBusStatus(uint32_t base)
{

    if(I2C_isBusBusy(base))
    {
        return ERROR_BUS_BUSY;
    }

    if(I2C_getStopConditionStatus(base))
    {
        return ERROR_STOP_NOT_READY;
    }

    return SUCCESS;
}

uint16_t handleNACK(uint32_t base)
{
    if(I2C_getStatus(base) & I2C_STS_NO_ACK)
    {
        I2C_clearStatus(base, I2C_STS_NO_ACK);
        I2C_sendStopCondition(base);

        return ERROR_NACK_RECEIVED;
    }

    return SUCCESS;
}

The code is stuck here:

 status = I2C_ControllerReceiver(&RTC); in this function and stucked at this function:          while(I2C_getStopConditionStatus(base) && attemptCount <= 3U);

//*****************************************************************************
//
//! Get stop condition status.
//!
//! \param base is the base address of the I2C instance used.
//!
//! This function reads and returns the stop condition bit status.
//!
//! \return Returns \b true if the STP bit has been set by the device to
//! generate a stop condition when the internal data counter of the I2C module
//! has reached 0. Returns \b false when the STP bit is zero. This bit is
//! automatically cleared after the stop condition has been generated.
//
//*****************************************************************************
static inline bool
I2C_getStopConditionStatus(uint32_t base)
{
    //
    // Check the arguments.
    //
    ASSERT(I2C_isBaseValid(base));

    //
    // Check the stop condition bit and return appropriately.
    //
    return((HWREGH(base + I2C_O_MDR) & I2C_MDR_STP) != 0U);
}

Some helpful hints would truly be appreciated! 

  • Hello Gianni,

    I'm using different C2000microcontroller (TMS320F28386D), RTC (ISL12022M) and from Datasheet I have not clear what is the address to use: I supposed that the correct address is 0x6F:

    That seems correct based on what I understand from the description.

    But I'm not clear how to set the Read/Write bit in the code. In my case, I have to set 1 for read operation, but where have I to set this value?

    This is done with the I2C_setConfig function which will configure the I2C peripheral for sending or receiving. The bus scan function you're looking at is just for scanning the bus to see what's connected, it doesn't transmit/receive anything (I believe it shouldn't).

    The code is stuck here:

     status = I2C_ControllerReceiver(&RTC); in this function and stucked at this function:          while(I2C_getStopConditionStatus(base) && attemptCount <= 3U);

    This means that the there is no stop condition detected. Did you make sure that the bus scan function returned a success for the addresses provided to it? If not, it may be the case that it didn't properly communicate with the device or the incorrect address was used.

  • This is done with the I2C_setConfig function which will configure the I2C peripheral for sending or receiving. The bus scan function you're looking at is just for scanning the bus to see what's connected, it doesn't transmit/receive anything (I believe it shouldn't).

    Do you mean that this function sets automatically the r/w bit? So, I have not to set the r/w bit, is it correct?

  • Do you mean that this function sets automatically the r/w bit? So, I have not to set the r/w bit, is it correct?

    That's correct, the I2C peripheral is a peripheral, so it does a lot of those configurations for you when you set up the registers (in this case, the I2C_setConfig function sets the TRX bit to determine whether it's sending or receiving data). You can refer to the reference manual for more information on this.