I2c Master

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

We are using the CYBLE-022001-00 module in a project and need to send some commands to another device via the I2c bus. Is anyone aware of a sample project that covers this application?

0 Likes
1 Solution
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Welcome in the forum, William!

   

Byte I2C interface is quite simple: After setting up the component and starting it you use

   

    I2C_MasterSendStart(DeviceAddress,I2C_WRITE_XFER_MODE);    // Initialize a transaction for writing
    I2C_MasterWriteByte(Register);                // Indicate which register you want to write to
    I2C_MasterWriteByte(Value);                // Write to register
    I2C_MasterSendStop();                    // End of transaction

   

When you want to read from a device you use (example for reading two bytes

   

    I2C_MasterSendStart(DeviceAddress,I2C_WRITE_XFER_MODE);    // Initialize a transaction for writing
    I2C_MasterWrite(Register);                // Indicate which register you want to write to
    I2C_MasterSendRestart(DeviceAddress,I2C_READ_XFER_MODE);
    I2C_MasterReadByte(I2C_ACK_DATA);            // Read from register
    I2C_MasterReadByte(I2C_NAK_DATA);            // Read from register, last byte is NAKed
    I2C_MasterSendStop();                    // End of transaction

   

Not too difficult. Keep in mind that most of the APIs (except those for reading a byte) return a status byte which, when non-zero indicate an error condition.

   

 

   

Bob

View solution in original post

0 Likes
5 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Welcome in the forum, William!

   

Byte I2C interface is quite simple: After setting up the component and starting it you use

   

    I2C_MasterSendStart(DeviceAddress,I2C_WRITE_XFER_MODE);    // Initialize a transaction for writing
    I2C_MasterWriteByte(Register);                // Indicate which register you want to write to
    I2C_MasterWriteByte(Value);                // Write to register
    I2C_MasterSendStop();                    // End of transaction

   

When you want to read from a device you use (example for reading two bytes

   

    I2C_MasterSendStart(DeviceAddress,I2C_WRITE_XFER_MODE);    // Initialize a transaction for writing
    I2C_MasterWrite(Register);                // Indicate which register you want to write to
    I2C_MasterSendRestart(DeviceAddress,I2C_READ_XFER_MODE);
    I2C_MasterReadByte(I2C_ACK_DATA);            // Read from register
    I2C_MasterReadByte(I2C_NAK_DATA);            // Read from register, last byte is NAKed
    I2C_MasterSendStop();                    // End of transaction

   

Not too difficult. Keep in mind that most of the APIs (except those for reading a byte) return a status byte which, when non-zero indicate an error condition.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hi Bob,

   

Thanks for your welcome message on a different thread.

   

I have struggled with i2c master in the past and so your message above was quite useful. I have converted it into a sample function to read as follows.

   

   

uint32 read_data(uint8 SlaveAddr, uint8 Reg, uint8* Data) {

   

    uint32 errCode = 0;
    
    int sizeData = sizeof(Data);
    if (sizeData < 1)
        return 0x11u;
    
    errCode = I2C_I2CMasterSendStart(SlaveAddr, I2C_I2C_WRITE_XFER_MODE);
    if (errCode)
        return errCode;
    
    errCode = I2C_I2CMasterWriteByte(Reg);
    if (errCode)
        return errCode;
        
    errCode = I2C_I2CMasterSendRestart(SlaveAddr, I2C_I2C_READ_XFER_MODE);
    if (errCode)
        return errCode;
    
    CyDelay(15);
    
    if (sizeData == 1) {
        Data[0] = I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA);
        CyDelay(1);
    } else {    
        for ( int n=0; n<(sizeData-1); n++) {
            Data = I2C_I2CMasterReadByte(I2C_I2C_ACK_DATA);
            CyDelay(1);
        }
        Data[sizeData] = I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA);
        CyDelay(1);
    }
    
    errCode = I2C_I2CMasterSendStop();
    
    return errCode;
}

   

I will appreciate your critique/comments/thoughts on the above.

   

Regards,

   

Nayan.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

int sizeData = sizeof(Data); This will always be the size of a pointer. Since *Data is an uint8 there will be no chance to determine the amount of data to transfer, use an additional parameter.

   

Not quite clear what the CyDelays() are good for.

   

For easier debugging: Do not return the error, but call a function where you can set a single breakpoint. The call stack will show you where the error came from.

   

 

   

Bob

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Many thanks, Bob. Much appreciated.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You are always welcome, Nayan.

   

 

   

Bob

0 Likes