RTC DS1307 0xD0 address issue (using i2c)

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

cross mob
Anonymous
Not applicable

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.

scope.png

0 Likes
1 Solution

#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(;;)

    {

    }

}

Screen Shot 2018-05-01 at 1.14.19 PM.png

View solution in original post

0 Likes
13 Replies
lock attach
Attachments are accessible only for community members.
rola_264706
Level 8
Level 8
50 likes received 25 likes received 10 likes received

Compare your program to this code.  I am running this Psoc Creator  4.2 (4.2.0.641). Don't forget the Pull-up resistors on the SDA and SCL lines

0 Likes

use 0x68 as slave address. Cypress uses 7-bit addresses wich get shifted left having the R/W bit appended.

Bob

0 Likes
Anonymous
Not applicable

Looks like the answer is partially correct.  It only uses 7 bits, but doesn't shift.  Using 0x68  gave the output attached.scope_0x68.png

(It shows 0x68.  Note 0xF8  generates 0x78.)

0 Likes
Anonymous
Not applicable

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.

0 Likes
Anonymous
Not applicable

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

0 Likes

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

0 Likes

Bobs answer is correct.

I think that every single I2C API we have uses a 7-bit address.

0 Likes
Anonymous
Not applicable

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

0 Likes

1. No.

2. Yes... for sure.

Alan

0 Likes
Anonymous
Not applicable

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

0 Likes

#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(;;)

    {

    }

}

Screen Shot 2018-05-01 at 1.14.19 PM.png

0 Likes
Anonymous
Not applicable

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

0 Likes

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.

0 Likes