I2CSendBuf() not honoring Stop==false

Discussion to talk about software related topics only.
Post Reply
mstrzelczyk
Posts: 7
Joined: Fri Sep 05, 2014 6:51 am

I2CSendBuf() not honoring Stop==false

Post by mstrzelczyk »

System: MOD54415
NNDK Release 2.6.7

The function call I2CSendbuf(), when supplied with the argument "Stop" set to false, still issues a stop I2C signal. The particular device being addressed (LM75B temperature sensor) requires an I2C address byte PLUS an pointer address byte (when the internal pointer is changed). The subsequent LM75B read from that pointer specifies a RESTART. This seems to only be possible with low level functions. See attached for functional vs. non-functional.

I haven't seen any mention of this issue in release notes up to 2.7.3, so I haven't tried upgrading the NBEclipse NNDK.
Attachments
Screen captures of I2CSendbuf() vs. Low-level function calls
Screen captures of I2CSendbuf() vs. Low-level function calls
I2CSendBuf.jpg (128.43 KiB) Viewed 3223 times
mbrown
Posts: 61
Joined: Tue Jan 29, 2013 7:12 pm

Re: I2CSendBuf() not honoring Stop==false

Post by mbrown »

Looking at the code you posted below the Logic Analyzer's output, I would guess the I2CSendBuf is doing what it should be doing then when the ReadBuf command starts, it realizes no restart byte has been sent and restarts the bus so that it can send it's own address bus with an appropriate start. The way that you have to send a restart on the bus is unfortunately SendBuf, Restart, ReadBuf, even if you set the appropriate stop bit at the end of the function. Looking at the way you wrote your code, it would be convenient if you only had to call SendBuf, then ReadBuf, but there's no variables at the moment to keep track of whether we still own the bus and just need to restart it, so you'll have to use the restart function.

I've used the following functions to talk with registers on a temperature sensor for a couple examples around here and was successfully able to get the system to send with no extra stop and start bits.

Code: Select all


/* Use I2C to read a byte from the specified register on address 0x48 */
uint8_t read8(uint8_t reg) {
    uint8_t rx = 0;
    BYTE status = I2CSendBuf(I2C_TEMP_SENSOR_ADDRESS, &reg, 1, false);
    if ( status != I2C_MASTER_OK )
    	iprintf("Error %d calling I2CSendBuf()\r\n", status);

    status = I2CRestart( I2C_TEMP_SENSOR_ADDRESS, I2C_START_READ);
    if (( status != I2C_OK ) && (status != I2C_NEXT_READ_OK))
        iprintf("Error %d calling I2CRestart()\r\n", status);

    status = I2CReadBuf(I2C_TEMP_SENSOR_ADDRESS, &rx, 1);
    if ( (status != I2C_OK) && (status != I2C_NEXT_READ_OK) ){
    	iprintf("Error %d calling I2CReadBuf()\r\n", status );
    	 Master_ResetPeripheral();
    }
    return rx;
}

/* Use I2C to write a byte to the specified register on address 0x48 */
uint8_t write8(uint8_t reg, uint8_t value) {

    BYTE status = I2CSendBuf(I2C_TEMP_SENSOR_ADDRESS, &reg, 1, false);
    if ( status != I2C_OK )
    	iprintf("Error calling I2CSendBuf()\r\n");

    status = I2CRestart(I2C_TEMP_SENSOR_ADDRESS, I2C_START_WRITE);
    if (( status != I2C_OK ) && (status != I2C_NEXT_WRITE_OK))
        iprintf("Error %d calling I2CRestart()\r\n", status);

    status = I2CSendBuf(I2C_TEMP_SENSOR_ADDRESS, &value, 1);
    if ( status != I2C_OK )
    	iprintf("Error calling I2CSendBuf()\r\n");

    return status;
}

mstrzelczyk
Posts: 7
Joined: Fri Sep 05, 2014 6:51 am

Re: I2CSendBuf() not honoring Stop==false

Post by mstrzelczyk »

Thank you!
Post Reply