Problem with simple I2C Master

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

cross mob
LaPe_296836
Level 2
Level 2
First like received

I have lots of experience running I2C Master's with PSoC 5LP, but this is my first try with PSoC 6, and I'm pulling my hair out!  I've got it down to a very simple bit of code:

int

main( void )

{

    cy_stc_scb_i2c_master_xfer_config_t i2c_xfer_config;

    cy_stc_scb_i2c_context_t         i2c_context;

    uint8_t write_buf[1] = {0x0};

    __enable_irq(); /* Enable global interrupts. */

   

    I2C_MASTER_Start();

    while (1)

    {

        while (I2C_MASTER_MasterGetStatus() & CY_SCB_I2C_MASTER_BUSY) {}

        i2c_xfer_config.slaveAddress = CTP_I2C_ADDR;    // slave address (0x38)

        i2c_xfer_config.buffer = write_buf;             // buffer

        i2c_xfer_config.bufferSize = 1;                 // byte count = 1

        i2c_xfer_config.xferPending = 0;                // complete transfer (generate a STOP)

        Cy_SCB_I2C_MasterWrite(I2C_MASTER_HW, &i2c_xfer_config, &i2c_context);

        CyDelay(10);

    }

}

Running on CM4 core (using the DevKit 063).  The while condition is getting satisfied all the time, but no pin wiggling!  I've verified that I can wiggle the pin as GPIO.

I set a breakpoint in the ISR that is registered and enabled as part of  I2C_MASTER_Start();, and it never gets hit.

I don't see any how-to guides that use the simple I2C_MASTER_Start() method -- all of the examples do all of the steps at a lower level, including registering and enabling the interrupt.  BTW - for pins I'm using P6[4] and P6[5], configured as pullup-high, drive low, bidirs.

Any help at this point would be greatly appreciated!

Thanks!

Larry

0 Likes
1 Solution

Hi Larry,

I think that you are using PSoC Creator because you have I2C Start API with instance name. Please, confirm.

It might be a problem in the context you are passing to the Cy_SCB_I2C_MasterWrite. The I2C Component allocates own context and run initialization routine using it and you pass your empty context. I suggest to call:

I2C_MASTER_MasterWrite(&i2c_xfer_config);

OR

Cy_SCB_I2C_MasterWrite(I2C_MASTER_HW, &i2c_xfer_config, &I2C_MASTER_context);

The Component default pin configuration is Driver mode = Open Drain, Drives Low and Initial State = 1 (this requires external pull-up), to use internal change Driver mode to Resistive Pull-up.

Please, attach project if nothing above didn't help so I can try on my side.

Thanks,

-Sergii

View solution in original post

4 Replies
SanjeevG_16
Employee
Employee
10 likes received 10 likes given 5 likes given

Hi,

Can you elaborate more on the question. I did not have more clarity

1) So, the master I2C's SDA and SCL are at Port 6 (P6.4 and P6.5). Which GPIO is not wiggling. Are you observing the clock or the pin in the Slave.

2) Does the slave receive the data. Is there any way you could see it?

Thanks

0 Likes

1) So, the master I2C's SDA and SCL are at Port 6 (P6.4 and P6.5). Which GPIO is not wiggling. Are you observing the clock or the pin in the Slave.

Even if I lift SDA and SCL (P6.4 and P6.5) from the slave, the pins do not ever change state (the transaction would not get ACK'ed, but at least it would start).  The pins seem to be correctly configured, as they exhibit an RC time constant at RESET time that is consistent with passive pull up.

2) Does the slave receive the data. Is there any way you could see it?

There is no activity, at all, on either SDA or SCL.  Also, as I mentioned, there seems to be no I2C interrupt taken.  I have tried with and without FIFO enabled.

Any thoughts?

Thanks,

Larry

0 Likes

Hi Larry,

I think that you are using PSoC Creator because you have I2C Start API with instance name. Please, confirm.

It might be a problem in the context you are passing to the Cy_SCB_I2C_MasterWrite. The I2C Component allocates own context and run initialization routine using it and you pass your empty context. I suggest to call:

I2C_MASTER_MasterWrite(&i2c_xfer_config);

OR

Cy_SCB_I2C_MasterWrite(I2C_MASTER_HW, &i2c_xfer_config, &I2C_MASTER_context);

The Component default pin configuration is Driver mode = Open Drain, Drives Low and Initial State = 1 (this requires external pull-up), to use internal change Driver mode to Resistive Pull-up.

Please, attach project if nothing above didn't help so I can try on my side.

Thanks,

-Sergii

Thank you, thank you!!!

I have to say that the documentation is not good here.  In fact the I2C_MASTER_Start() is not documented for the new PDL version, and in fact the document states:

context - The pointer to the context structure cy_stc_scb_i2c_context_t allocated by the user. The structure is used during the I2C operation for internal configuration and data retention. The user must not modify anything in this structure.

It states that I have to allocate it!  But the newer API intrinsically allocates a context, I now understand!  Why this is the one that must be used, I'm not sure I understand, but it does work now!

Regards,

Larry

0 Likes