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.

DM3730: I2C Transmit Issue - Sends two bytes when only write one.

Part Number: DM3730

Edited: grammar and formatting

I am having issues with the sending I2C data with a bare metal solution. I looked at the omap-i2c driver for linux and the AM35xx starterware driver to generate my own bare metal driver for the DM3730. The driver works fine when sending only 1 byte of date at a time (setting I2C_CNT.DCOUNT to 1) but when I want to send multiple bytes (e.g setting I2C_CNT.DCOUNT to 2) things go wrong. For some reason, the system thinks there are two data bytes to send when I only write one byte to the I2C_DATA register. The I2C registers are 16 bit, but looking at the memory browser they are treated as 32-bit with the upper 16 bit the register you write to and the lower 16 bit a shadow copy of the upper register. For most of the registers, editing the shadow copy within the memory browser has no effect, you can only write to the upper 16 bits, then the shadow copy is updated. For the I2C_DATA register you can write to the upper and lower words. I currently have a work around to my issue by writing the two bytes of my i2c payload to the upper and lower words. The hardware sends out the lower word first, then the upper word. However, there has to be a better way to do this.

void I2C_Write(struct i2c_adapter cfg, struct i2c_msg msg, int stop)
{
        /* ^^ Excerpt only not full function ^^ */


        SetupI2C(cfg);
        unsigned short data;
        unsigned short status;
        /* Set i2c slave address */
        I2CMasterSlaveAddrSet(cfg.i2c_controller, cfg.slave_address);

        /* Data Count specifies the number of bytes to be transmitted */
        I2CSetDataCount(cfg.i2c_controller,msg.len);

        numOfBytes = I2CDataCountGet(cfg.i2c_controller);

        /* Clear Tx and Rx FIFO */
       I2CMasterClearFIFO(cfg.i2c_controller); // Set bits in the I2C_BUF register to clear the FIFOs

        /* Configure I2C controller in Master Transmitter mode */
        I2CMasterControl(cfg.i2c_controller, I2C_CFG_MST_TX);

        /* Generate Start Condition over I2C bus */
        I2CMasterStart(cfg.i2c_controller);

        if(stop)
            I2CMasterControl(cfg.i2c_controller, I2C_CFG_STOP);

        /* Get status */
        status = I2CMasterIntStatus(cfg.i2c_controller);

        if( (status & I2C_STAT_TRANSMIT_READY) >> I2C_STAT_XRDY_SHIFT)
        {
            unsigned int num_bytes = msg.len;
            while(num_bytes)
            {
                num_bytes--;
                data = 0;
                if(msg.len)
                {
                   data = *msg.buf++;
                   msg.len--;
                }
               /* Put data to data transmit register of i2c */
                I2CMasterDataPut(cfg.i2c_controller, data);  // Equivalent to HWREG(baseAddr + I2C_DATA, data); or *(int*)(baseAddr + I2C_CON) = data;
            }
        }

       /* ^^ Excerpt only not full function ^^ */
}