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.

MSP430FR5735 I2C Master receive problems using DriveLib for a battery charger IC

Other Parts Discussed in Thread: MSP430FR5735

I am using an MSP430FR5735 Microcontroller to talk to a battery charger IC. The process is simple, send a data register byte for the location that you want to read from, then read one byte.

I call the function charger_read_reg and send the register location that I want to read.

charger_read_reg(0x0C); // read from the charger at the defined address

//*****************************************************************************
// initialize I2C TX
//*****************************************************************************
void init_I2C_TX(void)
{
    EUSCI_B_I2C_initMasterParam param = {0};// TX
    param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
    param.i2cClk = CS_getSMCLK();
    param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS;
    param.byteCounterThreshold = 1;
    param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
    EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);
}

//*****************************************************************************
// initialize I2C RX
//*****************************************************************************
void init_I2C_RX(void)
{
    EUSCI_B_I2C_initMasterParam param = {0};// TX
    param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
    param.i2cClk = CS_getSMCLK();
    param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS;
    param.byteCounterThreshold = 1;
    param.autoSTOPGeneration = EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD;
    EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);
}

//*******************************************************************************************************************
// Charger read comms
//*******************************************************************************************************************
void charger_read_reg(C_REG_ADDR)       // read register routine for the charger
{

 init_I2C_TX();
 EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, CHARGER_SLAVE_READ_ADDRESS);  // Specify slave address
 EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);   // Set to transmit mode
 EUSCI_B_I2C_enable(EUSCI_B0_BASE);      // Enable I2C Module to start operations


 EUSCI_B_I2C_masterSendSingleByte(EUSCI_B0_BASE, C_REG_ADDR);   //Send single byte data.(address of register to read)
 while(EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE))
     {
         ;
     }

 init_I2C_RX();
 EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, CHARGER_SLAVE_READ_ADDRESS);  //Specify slave address
     EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);    //Set Master to receive mode
     EUSCI_B_I2C_enable(EUSCI_B0_BASE);        //Enable I2C Module to start operations

     c_0x0C_r = EUSCI_B_I2C_masterReceiveSingleByte(EUSCI_B0_BASE);

}

What's happening is that the register data is sent,  a long 1mS delay ( I don't know why there is a delay) then the read address is sent and I never get a NACK or data returned.

I am not sure that I am switching between TX and RX I2C modes correctly. Any Ideas?

  • UPDATE:

    initially I was sending the TX write slave address. So I changed it to the read slave address and back again. I still can't explain the 1ms delay between TX and RX packets, but maybe that's how long it takes to change. This still does not explain why the RX never responds.

    init_I2C_TX();
    EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, CHARGER_SLAVE_WRITE_ADDRESS); // Specify slave address
    EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE); // Set to transmit mode
    EUSCI_B_I2C_enable(EUSCI_B0_BASE); // Enable I2C Module to start operations

    EUSCI_B_I2C_masterSendSingleByte(EUSCI_B0_BASE, C_REG_ADDR); //Send single byte data.(address of register to read)
    while(EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE))
    {
    ;
    }


    I am looking at the charger, maybe there is a reason that it's not responding as in a setup issue.
  • Hi Gordon,

    On my test setup I will sometimes see issues until I add the following line before EUSCI_B_I2C_masterReceiveSingleByte():

        EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,
                                   EUSCI_B_I2C_RECEIVE_INTERRUPT0 +
                                   EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
                                   );

    See if this changes your setup any. However the issues seems to be more centered around the slave device not acknowledging the slave address sent. I'm confused about your 7-bit slave address, which is 6A for a write and 6B for a read. Typically the slave address stays the same and just the LSB (read/write bit) changes, 0 for write and 1 for read. This could be a typo or misunderstanding in the way the DriverLib processes read and write operations. Can you provide the specific battery charger IC being used?


    Regards,
    Ryan

  • Ryan,

      The address 0x6A write and 0x6B read is the 7 bit plus the direction bit. you could say the address is 0x35 plus the direction bit.

      Yes, it was an address issue.

      I needed to send 0x6A for TX and RX, which seems incorrect but it looks like the direction bit is & with the address of 0x6A having bit 0 = 0. Then the address is corrected for TX and RX. 

      Either way it's working. I have also found the reason for the 1mS delay. You have to send a repeat start between the TX and the RX not a stop.

      The problem is that DriverLib does not have a repeat start function. You have to send a stop after TX to change over to RX to resend the address to receive the data when using the DriverLib.

      I will have to write to a few registers to get the repeat start to be able to send the TX and RX in line without the delay.

    Thank you for your support.

     

  • Gordon,

    Glad to help you find the addressing issue. In previous projects I've used masterSendMultiByte commands followed by masterReceiveMultiByte logic to create a repeated start instead of a stop condition. The syntax doesn't quite follow since only one byte is sent but it works.

    Regards,
    Ryan

**Attention** This is a public forum