- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I'm trying to communicate with a sensor using I2C interface and I use the I2C Master (UDB) component in the PSoC creator 2.0 to do so.The reset is connected to '0' and the SDA, SCL connected to the sensor (slave) with pull-ups resistors. I used many times before I2C interface so I very familiar with the protocol. the problem is that this time I get a complete module with functions that from the datasheet I just can't understand how to make a simple reading from the slave's registers:
I need to access to the sensor's address and then access its registers using another address and then read the data and save it.
The protocol of the sensor interface is simple and standard:
Master|S|AD+W| |RA| |S|AD+R| | |NACK|P|
Slave | | |ACK| |ACK| | |ACK|DATA| | |
If someone can give me a simple code example for how to use the component's functions to make this all work I'll be very grateful...
Thanks,
Michael.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do not have a code-example at hand, but from your protocoll I can see (|AD-W| , |AD+R|) that you might try to modify the sllave's address to indicate a read or write operation. This is handled within the master-software, you just specify the slave's base address where you want to read from or write to.
You'll easily find an example when you right-click un your I2C-module in the schematic or in the component catalog and then click on "Find example Project" which will bring up a dialog where you select your device (PSoC 5). The example given is for an EZI2c-slave, but that will not matter for the master and for the addressing.
Hope that helps
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Bob for the reply,
I looked at that example before but I don't see how to address the registers after I address the device. Unlike the EzI2C In my case I use a device with registers... I'ts possible to invent the wheel all over again by writing the codes from scratch but I think that must be an easy way to do that using the I2C component functions which I just don't see/understand them from the datasheet or the EzI2C example...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It may be better if you can give us the part number or the specification of the slave devices?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The slave's datasheet: http://invensense.com/mems/gyro/documents/PS-MPU-6000A.pdf see pages 36 to 39
In my case the slave's address is: 0x68
The slave's register map: invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf
I need code example for reading/writing one of the data registers.
Thanks,
Michael H.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do not have an example-code right at hand, but it is a two-liner.
Have a look at the datasheet of the I2C Master/Multimaster/Slave module, page 19.
Use the
I2C_MasterReadBuf(SlaveAdr,&DataBuffer,2, I2C_MODE_COMPLETE_XFER);
That's all.
Bob
I2C_MasterWriteBuf(SlaveAdr,&RegisterNumber,1, I2C_MODE_NO_STOP);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The lines of the above code have gotten mangled, I suppose you can order them correctly again (Write first, then read).
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Bob for the support,
After alot of trying (and failing) the following code works:
int32 i;
uint8 wrData[1], rdData[2]; // Put in the wrData[0] array the register address
volatile uint8 status;
I2C_Start();
status = I2C_MasterSendStart(MPU6050_ADD, I2C_WRITE_XFER_MODE);
if(status == I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */
{
/* Send array of 1 bytes */
for(i=0; i<1; i++)
{
status = I2C_MasterWriteByte(wrData);
if(status != I2C_MSTR_NO_ERROR) break;
}
}
I2C_MasterSendStop(); /* Send Stop */
status = I2C_MasterSendStart(MPU6050_ADD, I2C_READ_XFER_MODE);
if(status == I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */
{
/* Read array of 2 bytes */
for(i=0; i<2; i++)
{
if(i < 1) rdData = I2C_MasterReadByte(I2C_ACK_DATA);
else rdData = I2C_MasterReadByte(I2C_NAK_DATA);
}
}
I2C_MasterSendStop(); /* Send Stop */
I2C_Stop();
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, looks a bit more than my twoliner... But fine that you've got it and thank you to share your code with us!
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi guys, I realise this post is very old, but I am hoping you can help me out.
I have to read from 16 bit sub address the I2C device. The different registers will be of different lengts, but the one i am attempting should have an array of four bytes.
To give you an example:
I will first write to the chip:
8bit chip address - 16 sub register - data
0x76 - 0x00 0xBF - 0x00 0xCA 0xDD 0xCF
When i read back all i see on the logic analyzer is the first byte ack, as shown in the attachement
I only tweaked your code slightly to accomedate for the 16 bit sub address and four bytes instead of 2:
uint16 msb = (regAddress >> 8);
uint16 lsb = regAddress;
int32 i;
volatile uint8 status;
status = DSP_I2CMasterSendStart(slavechip, DSP_I2C_WRITE_XFER_MODE);
if(status == DSP_I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */
{
/* Send array of 1 bytes */
for(i=0; i<1; i++){
status = DSP_I2CMasterWriteByte(msb);
if(status != DSP_I2C_MSTR_NO_ERROR) break;
status = DSP_I2CMasterWriteByte(lsb);
if(status != DSP_I2C_MSTR_NO_ERROR) break;
}
}
DSP_I2CMasterSendStop(); /* Send Stop */
status = DSP_I2CMasterSendStart(slavechip, DSP_I2C_READ_XFER_MODE);
if(status == DSP_I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */
{
/* Read array of 2 bytes */
for(i=0; i<4; i++)
{
if(i < 3)rdData = DSP_I2CMasterReadByte(DSP_I2C_ACK_DATA);
else rdData = DSP_I2CMasterReadByte(DSP_I2C_NAK_DATA);
}
}
DSP_I2CMasterSendStop(); /* Send Stop */
Any help would be much appreciated.
-Kat
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Btw, I have confirmed that the first byte read back is correct and not just always 0x00
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please, don't hijack old threads with new questions. This will hide your question, and you will get less answers. Just open a new thread.
Thanks,
hli
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What is the question you are having? What do you expect to happen, what what happens instead?
The LA screenshot shows you are trying to read register 0x008f, but your text said 0x00bf. And the LA also shows that three bytes are returned.
Maybe you can tell what you chip you are talking to? Typically, when reading a register, one doesn't send a stop bit after sending the address, but just another start condition. Maybe leaving out the SendStop() helps?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What is the question you are having? What do you expect to happen, what what happens instead?
The LA screenshot shows you are trying to read register 0x008f, but your text said 0x00bf. And the LA also shows that three bytes are returned.
Maybe you can tell what you chip you are talking to? Typically, when reading a register, one doesn't send a stop bit after sending the address, but just another start condition. Maybe leaving out the SendStop() helps?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I used SendStop() between writing the address and data(secondary address) via the I2C instead I used a Restart() when reading. When reading is finished the last instruction is a SendStop().
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh, I mixed up the read command with something which actually got already read from the I2C slave. Silly me (I'm too used to SPI... 😞
But I still see, after the 0x00 got read (and ACKed) that something happens on the I2C bus, but the LA doesn't seem to annotate it.
I suggest you a) upload the complete project, so we can look at the complete source code (maybe something else is off), and link to the datasheet of the chip you are communicating with (maybe the error is in the protocol...).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Mis-typed, sorry
Should read "I did NOT use SendStop() ....
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Bah....... that was it, it wanted resend instead of send.. *facepalm*
Thank you both, guys!
So my code working was:
uint16 msb = (regAddress >> 8);
uint16 lsb = regAddress;
uint8 i;
volatile uint8 status;
status = DSP_I2CMasterSendStart(slavechip, DSP_I2C_WRITE_XFER_MODE);
if(status == DSP_I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */
{
/* Write address of sub register */
status = DSP_I2CMasterWriteByte(msb);
if(status != DSP_I2C_MSTR_NO_ERROR) break;
status = DSP_I2CMasterWriteByte(lsb);
if(status != DSP_I2C_MSTR_NO_ERROR) break;
}
status = DSP_I2CMasterSendRestart(slavechip, DSP_I2C_READ_XFER_MODE);
if(status == DSP_I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */
{
/* Read array of 2 bytes */
for(i=0; i<cnt; i++)
{
if(i < (cnt-1))rdData = DSP_I2CMasterReadByte(DSP_I2C_ACK_DATA);
else rdData = DSP_I2CMasterReadByte(DSP_I2C_NAK_DATA);
}
}
DSP_I2CMasterSendStop(); /* Send Stop */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Congratulations to get it solved. Welcome to the wonderful world of PSoC!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hehe, thank you!