- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
I'm using the I2C master (Fixed Function, V3.5) and trying to communicate with a DS1307 Real Time Clock.
When I put the SCL and SDA lines on a scope / digital analyser it is showing the address as 0x50 instead of 0xD0 needed for the RTC. (It looks like it is dropping the first bit of the write command.
I'm using the CY8CKIT-059 PSoC 5LP prototyping kit. (Using 12_0 for SCL and 12_1 for SDA.)
My code is basically:
#define I2C_SLAVE_ADDR (0xd0u)
/* Delay between commands in milliseconds */
#define CMD_TO_CMD_DELAY (500u)
void main(void)
{
I2C_Start();
CyGlobalIntEnable;
for(;;)
{
ReadStatusPacket();
CyDelay(CMD_TO_CMD_DELAY); /* Delay between commands */
}
}
uint32 WriteCommandPacket(uint8 cmd)
{
uint8 buffer[BUFFER_SIZE];
uint32 status = TRANSFER_ERROR;
buffer[0] = cmd;
(void) I2C_MasterWriteBuf(I2C_SLAVE_ADDR, buffer, 1, I2C_MODE_COMPLETE_XFER);
/* Waits until master completes write transfer */
while (0u == (I2C_MasterStatus() & I2C_MSTAT_WR_CMPLT))
{
}
/* Displays transfer status */
if (0u == (I2C_MSTAT_ERR_XFER & I2C_MasterStatus()))
{
/* Check if all bytes was written */
if (I2C_MasterGetWriteBufSize() == 1)
{
status = TRANSFER_CMPLT;
}
}
else
{
status = TRANSFER_ERROR;
}
(void) I2C_MasterClearStatus();
return (status);
}
uint32 ReadStatusPacket(void)
{
uint8 buffer[BUFFER_SIZE];
uint8 my_cmd[2];
uint8 datacount =0;
uint32 status = TRANSFER_ERROR;
my_cmd[0] = 0xd0;
my_cmd[1] = 0xff;
(void) I2C_MasterWriteBuf(I2C_SLAVE_ADDR, my_cmd, 1, I2C_MODE_COMPLETE_XFER); // should set address/reg to read.
// Waits until master completes write transfer
while (0u == (I2C_MasterStatus() & I2C_MSTAT_WR_CMPLT))
{
}
// Displays transfer status
if (0u == (I2C_MSTAT_ERR_XFER & I2C_MasterStatus()))
{
// Check if all bytes was written
datacount = I2C_MasterGetWriteBufSize(); // how many bytes went out?
}
else
{
status = -1; // there was an error
}
(void) I2C_MasterReadBuf(I2C_SLAVE_ADDR, buffer, 6, I2C_MODE_COMPLETE_XFER );
/* Waits until master complete read transfer */
while (0u == (I2C_MasterStatus() & I2C_MSTAT_RD_CMPLT))
{
}
/* Displays transfer status */
if (0u == (I2C_MSTAT_ERR_XFER & I2C_MasterStatus()))
{
status = TRANSFER_CMPLT;
}
else
{
status = TRANSFER_ERROR;
}
(void) I2C_MasterClearStatus();
return (status);
}
=======================================================
thanks for any suggestions,
Bob
below is what I'm seeing on the scope.
Solved! Go to Solution.
- Labels:
-
PSoC 5 Device Programming
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
#include "project.h"
int main(void)
{
__enable_irq(); /* Enable global interrupts. */
CyDelay(500);
I2C_1_Start();
Cy_SCB_I2C_MasterSendStart(I2C_1_HW,0x68,CY_SCB_I2C_WRITE_XFER,10,&I2C_1_context);
Cy_SCB_I2C_MasterSendStop(I2C_1_HW,0x68,&I2C_1_context);
for(;;)
{
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
use 0x68 as slave address. Cypress uses 7-bit addresses wich get shifted left having the R/W bit appended.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Looks like the answer is partially correct. It only uses 7 bits, but doesn't shift. Using 0x68 gave the output attached.
(It shows 0x68. Note 0xF8 generates 0x78.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the code but it uses 7bit address (0x68) so it isn't plagued by the most significant bit being dropped as 0xD0 is. (See my response below to Bob's suggestion.)
thanks anyway.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
I haven't heard any more suggestions on this. I'm going to resort to bit-banging the data in/out of the DS1307 (RTC).
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, we didn't know that you haven't got it to work till now.
You need to use 7-bit wide slave addresses, all other needed bit banging is done with the component.
Every I2C API returns an error code (0 is success), check that.
Can you please post your complete project so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Bobs answer is correct.
I think that every single I2C API we have uses a 7-bit address.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm out of the office so I can't put together a simple test project at the moment.
Two quick questions:
1) Has anyone ever used this RTC DS1307 (with address 0xD0) it is a popular RTC with the PSoC chips?
2) Is there confirmation that the 7 bit address is shifted to the left and bit 0 is set by the read/write function. (I couldn't get it to appear on the scope, the most significant bit is always 0.)
thanks for the help,
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1. No.
2. Yes... for sure.
Alan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
can you capture it on a scope for me? I put 0x68 in and got 0x68 out. I put 0xF8 in and got 0x78 out as the address. (The goal was 0x68 would be shifted to make 0xD0 appear on the address line on the scope.)
thanks again,
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
#include "project.h"
int main(void)
{
__enable_irq(); /* Enable global interrupts. */
CyDelay(500);
I2C_1_Start();
Cy_SCB_I2C_MasterSendStart(I2C_1_HW,0x68,CY_SCB_I2C_WRITE_XFER,10,&I2C_1_context);
Cy_SCB_I2C_MasterSendStop(I2C_1_HW,0x68,&I2C_1_context);
for(;;)
{
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for posting that. It gave me a different look, even though you wrote 0x68 and the scope interpreted 0x68 the thing I just noticed is if I take it as 8 bits I get the 0xD0 (when including the read/write bit) The RTC probably is really 0x68 as the address (or 0xD0 | read/write bit.)
Thanks to you and others for walking me through that.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Cool.
To be 100% clear.
All of the Cypress I2C APIs use 7bit addresses.
When you send a start it:
issue the start
send the 7-bit address
sens either the read or write bit (either 1 or 0)
In the scope picure above I used a Saleae logic analyzer... and I configured it for 7-bit address... you can also configure it for 8bits in which case it would have shown 0x68<<1| (either 1 or 0 depending on read or write) ... so in this case it would have been 0x68<<1|0 = 0xD0
Hopefully that helps.