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.

TMS320F28069M: LSm9ds1 IMU sensor i2c interfacing

Part Number: TMS320F28069M
Other Parts Discussed in Thread: C2000WARE

Hello,

I am currently working on LSm9ds1 Imu sensor with TMS320F28069M micro controller. As no library available for this senosr. I created read write function for to read write register value . but i am facing some issue:

1. During communication SDA pin always high, (setting pin  SDA and SCL output to variable and observe the variable in debug mode) does it mean my data is not transferring or receiving  ? but SCL value changing .

Also I2CSTR -->NACK bit is 1 for first reading value after it set to zero it means that acknowledgement is received from  slave device. 

i2c for IMU sensor is :

                         init _i2c  with :

             I2CSAR -->0x68 for gyro sensor, then reading function: 
                1)start
	  	2) slave address + W  --> I2cSAR = D4
	  	3) slave ack
	  	4) slave subaddress
	  	5) slave ack
	  	6) start repeat
	  	7) slave address + R  -->I2CSAR = D5
	  	8) slave ack
	  	9) data
	  	10)NMAK
	  	11)stop
anybody have suggestion what mistake i am doing?
  • Hello Vasanth,

    To clarify, when you say there is no library for the sensor, does the sensor require a unique way of using I2C that C2000Ware is not able to replicate. If so, do you mind sending your code or at least an example of the code you're trying to run? I can at least try to verify that your code has the correct logic.

    Best regards,

    Omer Amir

  • Thank you for your reply.

    To clarify, when you say there is no library for the sensor, does the sensor require a unique way of using I2C that C2000Ware is not able to replicate.


    library for LSM9DS1 with arduino/STm controller is available.

    int32_t lsm9ds1_read_reg(stmdev_ctx_t *ctx, uint8_t reg,uint8_t *data,uint16_t len)
    {

      int32_t ret;

      ret = ctx->read_reg(ctx->handle, reg, data, len);

      return ret;
    }


    I want to implement reading and writing register value of IMU sensor with TMS28069M.

    My code for reading is:

    void I2C_init(LSM9DS1_Specs *LSM9DS1,I2C_Init *Init)
    //void I2C_init(void)
    {
        LSM9DS1->I2C_Regs = &I2caRegs;
    
      LSM9DS1->I2C_Regs->I2CPSC.all = 8;        // Prescaler - need 7-12 Mhz on module clk
      LSM9DS1->I2C_Regs->I2CCLKL = 45;          // NOTE: must be non zero
      LSM9DS1->I2C_Regs->I2CCLKH = 45;          // NOTE: must be non zero
      LSM9DS1->I2C_Regs->I2COAR = 0x00;//0; ////not using
      LSM9DS1->I2C_Regs->I2CSAR = 0x68; // Slave address
      LSM9DS1->I2C_Regs->I2CMDR.bit.FREE =0;
      LSM9DS1->I2C_Regs->I2CMDR.bit.BC = 8;
      LSM9DS1->I2C_Regs->I2CMDR.bit.DLB = 0
      LSM9DS1->I2C_Regs->I2CMDR.bit.XA = 0; //0-normal 7-bit addressing mode
      LSM9DS1->I2C_Regs->I2CMDR.bit.FDF = 0;
      LSM9DS1->I2C_Regs->I2CMDR.bit.STB = 0;
      LSM9DS1->I2C_Regs->I2CMDR.bit.IRS = 1;
      LSM9DS1->I2C_Regs->I2CMDR.bit.RM =  0;
      LSM9DS1->I2C_Regs->I2CMDR.bit.TRX = 1;
      LSM9DS1->I2C_Regs->I2CMDR.bit.MST = 1;
      LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 0;
      LSM9DS1->I2C_Regs->I2CMDR.bit.STT = 0;
      LSM9DS1->I2C_Regs->I2CIER.all = 0x24;      // Disable interrupts
      LSM9DS1->I2C_Regs->I2CFFTX.all = 0x6000;    // Enable FIFO mode and TXFIFO
      LSM9DS1->I2C_Regs->I2CFFRX.all = 0x2040;  // Enable RXFIFO, clear RXFFINT,
    
      //  printf("I2C Init done\t");
    }
    
    Uint16 I2CA_ReadData(LSM9DS1_Specs *LSM9DS1, I2CMSG *msg,Uint16 transfermode,Uint16 *data)
    {
        if (LSM9DS1->I2C_Regs->I2CMDR.bit.STP == 1)
            {
                printf("i2c_wr not ready!!!\n ");
                return I2C_STP_NOT_READY_ERROR;
            }
            // set in transmit mode
            LSM9DS1->I2C_Regs->I2CMDR.bit.TRX = 1;
            LSM9DS1->I2C_Regs->I2CCNT = 2; // setting the data count in the ICCNT register
            LSM9DS1->I2C_Regs->I2CSAR = 0xD4; // Slave address
    
            LSM9DS1->I2C_Regs->I2CMDR.bit.MST = 1;
    
            // setting the transfer mode
            if (transfermode == 1)
            {
                LSM9DS1->I2C_Regs->I2CMDR.bit.RM = 0; // S-A-D..(n)..D-P mode
                LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 1;
            }
            else if (transfermode == 2)
            {
                LSM9DS1->I2C_Regs->I2CMDR.bit.RM = 0; // S-A-D..(n)..D mode  (repeat n times)
                LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 0;
                //LSM9DS1->I2C_Regs->I2CCNT = length; // setting the data count in the ICCNT register
            }
            else if (transfermode == 3)
            { // S-A-D-D-D ... (repeat continuous) mode
                LSM9DS1->I2C_Regs->I2CMDR.bit.RM = 1;
                LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 0;
            }
    
            else
            { // if user specifies something else, go to idle mode
                LSM9DS1->I2C_Regs->I2CMDR.bit.RM = 0;
                LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 0;
            }
    
           // printf("transfermode : %x  \n", transfermode);
    
            if (LSM9DS1->I2C_Regs->I2CSTR.bit.BB == 1)
            {
                printf("\nBB_wr!!!");
                return I2C_BUS_BUSY_ERROR;
            }
    
    
            LSM9DS1->I2C_Regs->I2CMDR.bit.STT = 1;     //start
          //  printf("\n I2c_start.....");
    
           // LSM9DS1->I2C_Regs->I2CDXR = msg->wr_HighAddr;
    
          //  printf("\nwr_HighAddr:%x", LSM9DS1->I2C_Regs->I2CDXR);
    
    
            LSM9DS1->I2C_Regs->I2CDXR = msg->wr_LowAddr;
    
           // printf("\n wr_LowAddr:%x", LSM9DS1->I2C_Regs->I2CDXR);
    
            LSM9DS1->I2C_Regs->I2CMDR.bit.NACKMOD = 1; //The I2C module sends a NACK bit to the transmitter during the next acknowledge cycle on the bus.
    
            if (LSM9DS1->I2C_Regs->I2CSTR.bit.NACK == 1)
            {
                printf("\n_wrNACK not rx!!!");
    
                LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 1;
                LSM9DS1->I2C_Regs->I2CSTR.all = I2C_CLR_NACK_BIT;
            }
    
    
            LSM9DS1->I2C_Regs->I2CDXR = msg->reg_addr;
    
           // printf("\n _wrreg_addr :%x", LSM9DS1->I2C_Regs->I2CDXR);
    
            LSM9DS1->I2C_Regs->I2CMDR.bit.NACKMOD = 1; //The I2C module sends a NACK bit to the transmitter during the next acknowledge cycle on the bus.
    
            if (LSM9DS1->I2C_Regs->I2CSTR.bit.NACK == 1)
            {
                printf("\n_reg_NACK not rx!!!");
    
                LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 1;
                LSM9DS1->I2C_Regs->I2CSTR.all = I2C_CLR_NACK_BIT;
            }
    
            LSM9DS1->LSM9ds1_Regs.ctrl_reg8.bit.if_add_inc = 1;
    
            LSM9DS1->I2C_Regs->I2CMDR.bit.STB =1; //repeated start ;
            LSM9DS1->I2C_Regs->I2CMDR.bit.TRX = 0;
            LSM9DS1->I2C_Regs->I2CSAR = 0xD5;
    
    
          //  LSM9DS1->I2C_Regs->I2CDXR =  msg->rd_HighAddr;
            LSM9DS1->I2C_Regs->I2CDXR =  msg->rd_LowAddr;
         //   printf("\n rd_LowAddr : %x  \n",  LSM9DS1->I2C_Regs->I2CDXR );
    
            LSM9DS1->I2C_Regs->I2CMDR.bit.NACKMOD = 1; //The I2C module sends a NACK bit to the transmitter during the next acknowledge cycle on the bus.
    
            if (LSM9DS1->I2C_Regs->I2CSTR.bit.NACK == 1)
            {
                printf("\n rd_LowAddr_NO ACK2?");
    
                LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 1;
                LSM9DS1->I2C_Regs->I2CSTR.all = I2C_CLR_NACK_BIT;
            }
    
            *data++  =   LSM9DS1->I2C_Regs->I2CDRR;
    
            LSM9DS1->I2C_Regs->I2CMDR.bit.NACKMOD = 1; //The I2C module sends a NACK bit to the transmitter during the next acknowledge cycle on the bus.
    
            if (LSM9DS1->I2C_Regs->I2CSTR.bit.NACK == 1)
            {
                printf("\n rd_LowAddr_NO ACK2?");
    
                LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 1;
                LSM9DS1->I2C_Regs->I2CSTR.all = I2C_CLR_NACK_BIT;
            }
    
            *data++ = LSM9DS1->I2C_Regs->I2CDRR; // put next data value in DXR        //
            // Send data to setup EEPROM address
            //
            LSM9DS1->I2C_Regs->I2CMDR.all = 0x26B0; //0x26B0; //0x2620;
    
        printf("i2c complete!!!\n ");
    
        //LSM9DS1->I2C_Regs->I2CMDR.bit.STP = 1;//stop
    
        return LSM9DS1->I2C_Regs->I2CDRR;
    }
    
    
    

    Here is the library for LSM9DS1 with arduino/STm controller.

    https://github.com/STMicroelectronics/lsm9ds1-pid/blob/2d4d0282f4628c4eee820d55a48b8d3d8494e7c3/lsm9ds1_reg.c

    Help me to resolve this issue.

  • one more question is:

    Slave address should be in I2CSAR  register.  which one i should sent in I2CSAR either 0x60 or D4/D6.

    or that SAD+W value should set in I2CXDR register.

    Reading pattern is:

  • Hello Vasanth,

    Just to confirm, the library you are using is not the one provided by TI? If that is the case, is there some support from the creators of that library that could provide assistance?

    Also, if you can is it possible to provide a scope of the SDA and SCL signals?

    Best regards,

    Omer Amir