I2C Configuration , Read and Write

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

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hi,

   

i have configured the controller as I2C master and communicating with two slaves(RTC and EEPROM).

   

am not able to read the data from EEPROM (I have written data to the 0x0002 address).

   

please let me know about I2C configuration and Read and write function use.

   

 

   

 int main()
{
    
    CyGlobalIntEnable; /* Enable global interrupts. */

    I2CMasterIntilization();
    g_ucEEPROMWriteBuffer[0] = 0x00;
    g_ucEEPROMWriteBuffer[1] = 0x02;
    g_ucEEPROMWriteBuffer[2] = 0x05;
    g_ucEEPROMWriteBuffer[3] = 0x45;
    while(1)
    {
        WriteDataToEEPROM(3);
        g_ucEEPROMWriteBuffer[0] = 0x00;
        g_ucEEPROMWriteBuffer[1] = 0x02;
        ReadDataFromEEPROM(2);
    }

   

}

   

 

   

void I2CMasterIntilization(void)
{
    I2C_Master_Start();
}

   

void WriteDataToEEPROM(char chDataByte)
{
         I2C_Master_I2CMasterWriteBuf(EEPROM_SLAVE_ADDRESS,(unsigned                             char*)g_ucEEPROMWriteBuffer,chDataByte,I2C_Master_I2C_MODE_COMPLETE_XFER);
    while((I2C_Master_I2CMasterStatus() & I2C_Master_I2C_MSTAT_WR_CMPLT) == LOW)
    {
    }
    CyDelay(3);
}

   

void ReadDataFromEEPROM(char unNoOfDataByteNeedToReceive)
{
   
    I2C_Master_I2CMasterWriteBuf (EEPROM_SLAVE_ADDRESS,(unsigned char     *)g_ucEEPROMWriteBuffer,2,I2C_Master_I2C_MODE_COMPLETE_XFER);
    //CyDelay(1000);

   


    while((I2C_Master_I2CMasterStatus() & I2C_Master_I2C_MSTAT_WR_CMPLT) == LOW)
    {
    }

   


    I2C_Master_I2CMasterReadBuf(EEPROM_SLAVE_ADDRESS,(unsigned char *)g_ucEEPROMReadBuffer,unNoOfDataByteNeedToReceive,I2C_Master_I2C_MODE_REPEAT_START);
    while((I2C_Master_I2CMasterStatus() & I2C_Master_I2C_MSTAT_RD_CMPLT) == LOW)
    {
    }
}

   

 

   

if I use I2C_Master_I2C_MODE_NO_STOP while writing data from master , then clock will become low after transmitting data (SCL line is low). I used I2C_Master_I2C_MODE_COMPLETE_XFER to write the data , then wring is working fine and SCL and SDC lines are high after writing data to EEPROM.

   

 

   

kindly let me know about API's which I used in my coding.

   

please find the attached I2C module setting image. 

   

 

   

Regards,

   

Ambarish BH 

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

The I2C high-level APIs must be used in this way:

   

Writing to slave Count bytes
I2C_MasterWriteBuf(SlaveAddress,DataPtr,Count,I2C_MODE_COMPLETE_XFER);

   

Reading from Slave sending address first:
I2C_MasterWriteBuf(SlaveAddress,&EEPromAddress,2,I2C_MODE_NO_STOP);
I2C_MasterReadBuf(SlaveAddress,DataPtr,Count,I2C_MODE_REPEAT_START);

   


Bob

View solution in original post

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

The I2C high-level APIs must be used in this way:

   

Writing to slave Count bytes
I2C_MasterWriteBuf(SlaveAddress,DataPtr,Count,I2C_MODE_COMPLETE_XFER);

   

Reading from Slave sending address first:
I2C_MasterWriteBuf(SlaveAddress,&EEPromAddress,2,I2C_MODE_NO_STOP);
I2C_MasterReadBuf(SlaveAddress,DataPtr,Count,I2C_MODE_REPEAT_START);

   


Bob

0 Likes
Anonymous
Not applicable

is it possible to connect 2 external devices to a psoc 3 via I2C ? i've tried a bunch of different things, but without success... does psoc 3 only have one I2C bus or does it allocate one per I2C component? all i want to do is send info from A to B, have B send it to C then have C send it back to B and B back to A... i did it successfully in with a psoc 1, and somewhat in with a psoc 4; both of these take 2 i2c components; psoc 3 won't, so i tried to use the multi-master-slave, but this only seems to allow 2 pins to attach to it.. i have 2 external devices, so i need 4 pins... did a fixed and udb on psoc 3... separately (A to B, B to A, then B to C, C to B) they worked, but put them together, they freak

   

i'm beginning to suspect there's only one bus and the components are stepping over each other... is this the case?

0 Likes
AnkitaS_51
Employee
Employee
100 likes received 50 likes received 25 likes received

You can connect two devices on a single I2C bus too and can have communication among them sequentially.Why as such there is need for 4 pins

0 Likes
Anonymous
Not applicable

How do you do this? wouldn't you have to add the pins to the i2c component (multi-master-slave mode) in the "top design" page of the psoc creator 4? i don't see where/how to do that...

0 Likes
Anonymous
Not applicable

is "why as such there is need for 4 pins" a q? are you implying, to use a bus, i should use 2 pins on the component and connect all the devices to these pins via breadboard (or whatever) ?

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

The I2C bus distinguishes between master and slaves. In the normal configuration there is one master addressing several slaves (up to ~100).

   

To connect a slave device you will need to know its "Address" which is a factory pre-programmed value between 0x01 and 0x7e. Some chips allow for modifying the lower address bits using input pins.

   

I2C lines sda and scl need pullup resistors of 2 to 5K.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

can the psoc 3 have > 1 I2C bus?

   

I've successfully gotten a psoc 3 to connect to a slave (external chip); also, separately gotten the psoc 3 to be a slave to an Aardvark.

   

If the psoc 3 can have 2 I2C buses, i should be able to have the psoc 3 be a master to one thing and a slave to another? I've done this on psoc1 and 4 (though with 4 had to keep powercycling the chip to keep it working, so obviously something was screwy)

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

In Creator on the very right hand side of the window is a tab named resource meter which will help you estimating resource usage.

   

You may have one I2C master and several I2C slave components (UDB based)

   

 

   

Bob

0 Likes
Anonymous
Not applicable

ok, got the thing working with a fixed function master and a udb (with fixed placement) slave...

   

the two things i changed to make this work were

   

1) changing udb slave to fixed placement... why didn't it work before i chose this? in the datasheet i reads like this is just to improve performance..

   

i was just trying things since i was a wee peeved the thing wasn't working... i'd like to know why that made it work

   

2) psoc 4 creator had assigned the udb slave Reset pin to P12[2], which doesn't seem to exist on the device pinout... the project i'd created with the udb slave only had set it to a different pin, and i'd blindly aped it, and voila, it worked

   

so why did psoc creator 4 betray me? or tell me "hey, idiot, there's no pin there... stop being a bad person"...

   

i case you didn't guess, i'm new to this (electronics and psoc)

   

and just to be clear, 2 components ==> 2 buses? that seems to be how it's acting, but enquiring minds want to know... is the number buses limited to the number of scl/sda pin pairs on the psoc (with a pec of pickled peppers?)

   

finally, i'd be curious to make the single master, multi slave single bus work, (have set up a project with a single multi-master-slave component), so ref above q (i.e, just connect them all to same line? via bread board, at the moment)... is there a performance advantage to having everyone on one bus? i'll always have only 3 players... 2 externals, + the mighty psoc

   

thanks for your consideration

0 Likes
Anonymous
Not applicable

Hey,@

i got the solution please try this code as reference,

#include "project.h"

#define Dev_Address 0x50 //EEPROM Address

uint8 Data_R[2];

uint8 Data_Write[4] = {0x00,0x00,0x01,0x00};//first two byte is address for eeprom location

uint8 ReadAdd[2]={0x00,0x00};//this is for read eeprom location

int main(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    I2C_Start();

   

        //////////Write in the EEEPROM Using This Function

        I2C_I2CMasterWriteBuf(Dev_Address,(uint8 *)Data_Write, 4,I2C_I2C_MODE_COMPLETE_XFER);

        while(1){if(0u != (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT)){break;}}CyDelay(3);

        //////////READ STEP 1- Write First Address of Location for Read The the data         

        I2C_I2CMasterWriteBuf(Dev_Address,(uint8 *) ReadAdd, 2,I2C_I2C_MODE_NO_STOP);

        while(1){if(0u != (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_WR_CMPLT)){break;}}CyDelay(3);

        //////////READ STEP 2- Now Read the Data

        I2C_I2CMasterReadBuf(Dev_Address,(uint8 *)Data_R, 2,I2C_I2C_MODE_REPEAT_START);

        while(1){if(0u != (I2C_I2CMasterStatus() & I2C_I2C_MSTAT_RD_CMPLT)){break;}}CyDelay(3);

       

        /////////Now Use the data recieved

        led1_Write(Data_R[0]);  //put data on led to confirm that data got or not

        led2_Write(Data_R[1]);

}

0 Likes

Thank you for posting the code. I am learning I2C now and this has been helpful.

0 Likes