lpcware

UM10601 Rev. 1.6 — 2 April 2014 - I2C code examples have incorrect code

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by larryvc on Mon Jan 05 20:30:56 MST 2015
What happens when you bitwise inclusive OR a value with 0?

Many of the I2C code examples in UM10601 pages 340-347 have entries like this where the code is ORing a value with 0.  (Also, some of the comments do not match the operations.  These are obviously write operations.)  Sorry NXP, this is cut and paste without verification, again. :~

LPC_I2C->MSTDAT = (0x23 << 1) | 0; // address and 1 for RWn bit in
                                   // order to read data

LPC_I2C->MSTDAT = (0x23 << 1) | 0; // address and 0 for RWn bit in order to write
                                   // subaddress


Granted, bit 0, the RWn bit, is being cleared by the left shift anyway, but to do this correctly, and to not confuse new users, the code needs to be written like this to clear the RWn bit:

LPC_I2C->MSTDAT = (0x23 << 1) & ~(1<<0);


ORing with 1 for the read operations is correct in the code examples but could also be written as:

LPC_I2C->MSTDAT = (0x23 << 1) | (1<<0);

From the UM: (reformatted for posting)

Table 308. I2C Code example
Interrupt handler

void I2c_IRQHandler() {
uint32_t intstat = LPC_I2C->INTSTAT;
uint32_t stat = LPC_I2C->STAT;
    if(intstat & I2C_STAT_MSTPENDING) {
        uint32_t mst_state = stat & I2C_STAT_MSTSTATE;
        if(mst_state == I2C_STAT_MSTST_IDLE) {
            LPC_I2C->MSTDAT = (0x23 << 1) | 1; // address and 1 for RWn bit in order to read data
            LPC_I2C->MSTCTL = I2C_MSTCTL_MSTSTART; // send start
        }
        if(mst_state == I2C_STAT_MSTST_RX) {
            uint8_t data;
            data = LPC_I2C->MSTDAT; // receive data
            if(data != 0xdd) abort();
            LPC_I2C->MSTDAT = (0x23 << 1) | 0; // address and 1 for RWn bit in order to read data
            LPC_I2C->MSTCTL = I2C_MSTCTL_MSTSTART; // repeated start (nack implied)
        }
        if(mst_state == I2C_STAT_MSTSTX) {
            LPC_I2C->MSTCTL = I2C_MSTCTL_MSTSTOP; // stop transaction
            LPC_I2C->INTENCLR = I2C_STAT_MSTPENDING;
        }
    }
}

Outcomes