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.

C6748 DSPBIOS I2C Problem Reading from Freescale MMA8451Q Accelerometer

We use DSPBIOS to build our application with. I'm having difficulty getting a Freescale MMA8451Q Accelerometer running on one of theC6748's I2C buses. Specifically, I can't get it to read any of its internal registers. No matter which register I pick, I receive nothing but 0's.The research I've done indicates that the device requires a repeated start condition. Freescale mentions this in their data sheet - they refer to it as a repeated start condition (SR). Since the driver I'm creating needs to run with and I2C bus driver that is supported by DSPBIOS, I have to follow the conventions of TI's PSP IOM. The problem is, I haven't been able to figure out how to get the PSP I2C driver to send a repeated start condition. The device-level code I've created does generate the proper sequences but it generates a Stop in between the register selection and write command and the register read command instead of the required SR.

There are a set of macros available for controlling various flags listed int the PSP I2C.h file, here are a few:

 /** Default read flag                                                         */
#define I2c_DEFAULT_READ    (I2c_READ  | I2c_MASTER | I2c_START | I2c_STOP)

/** Default write flag                                                        */
#define I2c_DEFAULT_WRITE   (I2c_WRITE | I2c_MASTER | I2c_START | I2c_STOP)

There are a couple that I though might be of use but I tried them and they didn't work:

/** Repeat mode as per TI I2C specs                                           */
#define I2c_REPEAT          0x2000u

/** Re-Start is generated by Master                                           */
#define I2c_RESTART         0x400u

I know that the C6748 I2C hardware supports this mode of operation because I located it in one of the datasheets for the chip. I've also seen some bae metal driver code that shows how to setup the internal registers to get repeated start condition working. I'm reluctant to go down this path because we are running DSPBIOS and I read a warning that stated one should not drill down into the hardware and change register values outside of the RTOS environment as it can cause problems.

  • Hi Tom,

    Welcome to the TI E2E forum. I hope you will find many good answers here and in the TI.com documents and in the TI Wiki Pages (for processor issues). Be sure to search those for helpful information and to browse for the questions others may have asked on similar topics (e2e.ti.com).

    Checkout below thread, problem seems to be relevant.
    and let us know does it helps you out.
    e2e.ti.com/.../169259
    e2e.ti.com/.../114552
  • Hi Arvind,

    I found the links you sent useful but I'm working within the context of DSPBIOS not in a bare metal environment. You got me in the ballpark with the Repeat Start Condition. I found a nice illustration  in the I2C-Bus.org doc: http://www.i2c-bus.org/repeated-start-condition/ which showed me the timing diagram that I needed to see. Working with PSPIOM you need to pass Flag values inside of a data structure that enables you to control the I2C Bus protocol characteristics. There are a series of macros for the Flags, these macros live in the pspdrivers directory in a file labeled: I2c.h but there isn't a macro for Repeated Start so I created one that uses the I2c_RESTART macro I found in the file. Repeated Start actually removes STOP from the byte transfer operation which is what makes the operation Atomic so you need to add STOP to the last byte transfer in your protocol or the bus gets stuck in a Low state and no longer works.

    Here are the macros I use that pertain to Repeated Start:

    // Used for the Accelerometer to restart the Read after I2c_RESTART_WRITE

    #define I2c_RESTART_READ (I2c_READ | I2c_MASTER | I2c_RESTART)

    // Used when a Restart is required for the last I2C operation before releasing the bus

    #define I2c_RESTART_READ_STOP (I2c_READ | I2c_MASTER | I2c_RESTART | I2c_STOP)

    // Used to restart a Write

    #define I2c_RESTART_WRITE (I2c_WRITE | I2c_MASTER | I2c_RESTART)

    // Used to restart the Write when it is the last byte operation - it releases the bus

    #define I2c_RESTART_WRITE_STOP (I2c_WRITE | I2c_MASTER | I2c_RESTART | I2c_STOP)

    These work for me so I'm up and running now with the MMA8451Q.

    Thanks for pointing me in the right direction.

    Tom