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.

Rm46 i2c read from a slave device.

Other Parts Discussed in Thread: HALCOGEN

Hello ,

I have an IMU with a slave address of 0x20.

it has different register addresses from where we can get 8 bit of data  e.g 0x08,0x10,0x12 .

I Succeeded in doing i2c communication between TI TM4C123. But now i have to do communcation between Rm46x and this IMU.

I am a bit confused with the example given in the halcogen. i am following the example something like this. I just want to read 8 bit of data from register address of 0x08.

#include "sys_common.h"


#include "i2c.h"

#define Slave_Address 0x20

#define Slave_Register_address 0x08

#define DATA_COUNT  8

uint8_t RX_Data_Master[8] = { 0 };

void main(void)

{

int repeat = 0; int delay =0;

i2cInit();

/

i2cSetSlaveAdd(i2cREG1,Slave_Address);
/* Set direction to Transmitter */
/* Note: Optional - It is done in Init */
i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
/* Configure Data count */
i2cSetCount(i2cREG1, DATA_COUNT);
/* Set mode as Master */
i2cSetMode(i2cREG1, I2C_MASTER);
/* Set Stop after programmed Count */
i2cSetStop(i2cREG1);
/* Transmit Start Condition */
i2cSetStart(i2cREG1);
/* Send the Register Address */
i2cSendByte(i2cREG1, Slave_Register_address);
/* Wait until Bus Busy is cleared */
while(i2cIsBusBusy(i2cREG1) == true);
/* Wait until Stop is detected */
while(i2cIsStopDetected(i2cREG1) == 0);
/* Clear the Stop condition */
i2cClearSCD(i2cREG1);
/*****************************************/
/*****************************************/
/* wait until MST bit gets cleared, this takes
* few cycles after Bus Busy is cleared */
while(i2cIsMasterReady(i2cREG1) != true);
/* Configure address of Slave to talk to */
i2cSetSlaveAdd(i2cREG1, Slave_Address);
/* Set direction to receiver */
i2cSetDirection(i2cREG1, I2C_RECEIVER);
/* Configure Data count */
/* Note: Optional - It is done in Init, unless user want to change */
i2cSetCount(i2cREG1, DATA_COUNT);
/* Set mode as Master */
i2cSetMode(i2cREG1, I2C_MASTER);
/* Set Stop after programmed Count */
i2cSetStop(i2cREG1);
/* Transmit Start Condition */
i2cSetStart(i2cREG1);
/* Tranmit DATA_COUNT number of data in Polling mode */
i2cReceive(i2cREG1, DATA_COUNT, RX_Data_Master);
/* Wait until Bus Busy is cleared */
while(i2cIsBusBusy(i2cREG1) == true);
/* Wait until Stop is detected */
while(i2cIsStopDetected(i2cREG1) == 0);
/* Clear the Stop condition */
i2cClearSCD(i2cREG1);
asm(" nop");
asm(" nop");
asm(" nop");
while(1);
/* USER CODE END */
}
  • Hi Hassan,
    Do you just want to read from one register address?

    If this is the case then you don't want to define the DATA_COUNT 8 but instead should be just 1.

    Also I think you want to swap the order of the below two APIs.

    /* Send the Register Address */
    i2cSendByte(i2cREG1, Slave_Register_address);
    /* Transmit Start Condition */
    i2cSetStart(i2cREG1);
  • Thankyou for your reply

    i have this code for the TM4C123 and working good with th IMU. and i translated this code for the hercules rm46x

    int32_t I2CReceive(int32_t slave_addr, int8_t reg)
    {
    //specify that we are writing (a register address) to the
    //slave device
    I2CMasterSlaveAddrSet(I2C3_BASE, slave_addr, false);

    //specify register to be read
    I2CMasterDataPut(I2C3_BASE, reg);

    //send control byte and register address byte to slave device
    I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C3_BASE));


    //specify that we are going to read from slave device
    I2CMasterSlaveAddrSet(I2C3_BASE, slave_addr, true);

    //send control byte and read from the register we
    //specified
    I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

    //wait for MCU to finish transaction
    while(I2CMasterBusy(I2C3_BASE));

    //return data pulled from the specified register
    return I2CMasterDataGet(I2C3_BASE);
    }



    the translated code is

    int32_t I2CReceive(int32_t slave_addr, int8_t reg)
    {
    i2cSetSlaveAdd(i2cREG1, slave_addr);
    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
    i2cSendByte(i2cREG1,reg);
    i2cSetMode(i2cREG1, I2C_MASTER);
    i2cSetStart(i2cREG1);
    while(i2cIsBusBusy(i2cREG1) == true);

    i2cSetSlaveAdd(i2cREG1, slave_addr);

    i2cSetDirection(i2cREG1, I2C_RECEIVER);

    i2cReceiveByte(i2cREG1);
    printf("check: %i\n", 1);
    i2cSetStart(i2cREG1);

    while(i2cIsBusBusy(i2cREG1) == true);


    return 0;

    }


    but it is stuck at i2cReceiveByte(i2cREG1) and doesnt go further...
  • Hi,
    I cannot comment on the TM4C I2C. It is a different IP module from the one used in RM46x.

    You might want to check out the example_i2c_pcf8570 as well. Please go to HalCoGen->Help->Help Topics->examples->example_i2c_pcf8570.

    The RM46x i2C shares the same IP with the TI DSP device. Here is one document which contains flowcharts (from section 7.3) on how to transmit and receive for the master.

    www.ti.com/.../spru175d.pdf
  • i checked this documentation.. and changed my code from this documentation and previous posts from the TI forum. I2CSAR and and I2CDXR receive correct addresses everytime but when i use the i2cReceiveByte function it got stuck there for infinite time.. I have tried lots of thing and didnt succeeded so far.. i am using this IMU github.com/.../tutorial

    my code is...

    int32_t I2CReceive(int32_t SLAVE_ADDRESS, int8_t reg)
    {
    while(i2cIsBusBusy (i2cREG1) == true);
    i2cREG1->MDR = I2C_RESET_OUT;
    i2cSetMode(i2cREG1, I2C_MASTER);
    i2cSetSlaveAdd(i2cREG1, SLAVE_ADDRESS);
    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
    i2cSetCount(i2cREG1, 1);
    i2cSetStart(i2cREG1);
    while((i2cREG1->STR & (I2C_TX | I2C_ARDY)) == false); // To wait for the tx ready and register access ready
    i2cSendByte(i2cREG1, reg);
    // Start receiving the data from slave
    // wait for ARDY before beginning the read phase of the transaction
    while((i2cREG1->STR & I2C_ARDY) == false);
    i2cREG1->MDR = I2C_RESET_OUT; // To set the MDR with I"C is out of reset

    i2cSetMode(i2cREG1, I2C_MASTER);
    i2cSetDirection(i2cREG1, I2C_RECEIVER);
    i2cSetCount(i2cREG1, 1);
    i2cSetStop(i2cREG1);
    i2cSetStart(i2cREG1);
    // To receive one byte
    uint8 j;
    for(j = 0; j < 1; j++)
    {
    while((i2cREG1->STR &(I2C_RX | I2C_ARDY)) == true);
    sensTemp[j] = i2cREG1->DRR;
    }

    while(i2cIsBusBusy (i2cREG1) == true);
    /* Wait until Stop is detected */
    while(i2cIsStopDetected(i2cREG1) == false);
    /* Clear the Stop condition */
    i2cClearSCD(i2cREG1);
    return sensTemp[0];
    }



    When i use the uint8 i2cReceiveByte() it got stuck and when i try to get data directly through the I2CDDR register it shows 0. so i think the data has not been copied from I2CRSR to I2CDRR everytime.
  • when i put the i2cSetStop(i2cREG1); after the loop(sensTemp[j] = i2cREG1->DRR;) then i get the DEFAULT values of the register from my IMU but get 0 from the data registers... and the value in the status register (I2CSTR) is 0x00002418 which means ICRRDY,ICXRDY,XSMT and NACKSNT is 1 ...
  • What do you mean the DEFAULT value? What value is it? Did you have a chance to use a scope to probe the SDA and SCL lines. Are you receiving the correct data on the bus? Do you have proper pull-up on the bus?
  •  The IMU has two register id and status both have default values.yes i am using 5k of pullup resistors...i removed the pull up resistors and suddenyl got the data and then i again use the pullup  and still getting data. i dont know how and why that happened..

  • Good, so you are getting the data you want. I can't tell what happened when something wasn't working becomes working suddenly. I'm surprised to hear that without the pullup it will receive data. The protocol relies on the pullup for logic high. 

  • Hi Hassan,

    Is your question answered? if your question is answered can you please click the 'Verify Answer' to close the thread? Thanks.