PSoC5LP I2C: How can I ensure that SDA/SCL are starting high (idle)?

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

cross mob
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Hello!

I'm having some issues with using Master I2C on a PSoC5LP.  I'm working with a FM24C16B I2C FRAM and I'm finding that my I2C bus with this FRAM is sometimes coming up with either one or both signals low.  The problem comes when I'm running with debugger attached (MiniProg3) then attempt to reset (Shift-Alt-F5) , it will frequently result in I2C being stuck with either both lines or one line (usually SDA) being held low, and I can't seem to get the bus back into idle state until I power cycle the entire board.

I have 2k resistors for pull-ups and the I2C pins are both set as Bidirectional Open Drain Drive Low with Initial Drive State set to High.  The FRAM is the only device on this I2C bus, so the only thing I can imagine happening is maybe the reset is occurring during a transmission and the FRAM is holding SDA low.  This should not be occurring though, as the only time I am accessing the FRAM is on bootup, or when I send serial commands to write it from a host PC.

Does someone maybe have a way I could ensure SDA and SCL are initialized to a correct idle state upon startup?  I tried doing a "dummy" transmission (just a start condition to address 0x00 followed by a stop condition) after calling I2C_Start() thinking that would get the bus back to idle but this has not worked.  This in theory should not be an issue in production as there is no situation (other than maybe entering the bootloader) where the PSoC will be resetting while the system keeps power, but in testing it's proving to be rather annoying to have to constantly power cycle the system when I only want to reset the PSoC in the debugger.

Any suggestions would be appreciated,

Thanks!

[EDIT]

I have found (via logic analyzer) what looks to be happening is that when I attach the debugger or reset via debugger, some code runs before it brings the PC back to 0 and breaks at the beginning of main().  It looks like sometimes this can occur in the middle of an I2C transaction with the FRAM, leaving the bus in a non-idle state.  Presumably the FRAM is holding SDA low while waiting for a clock from the PSoC.  Putting a 1 second delay before I2C traffic begins looks to "solve" the issue, but any other suggestions to ensure the bus is idle on bootup would be appreciated.

0 Likes
1 Solution

KyTr,

Got it.  The FRAM was in the middle of a SDA out and the clocks stopped coming in (because the I2C master reset) to clock the remaining data out of the FRAM (read op).  I'd be more concerned with a partial write to FRAM.  Are you using a checksum or CRC with your data?

What FRAM are you using?

I spotted this at https://i2c.info/i2c-bus-specificationhttp://

pastedImage_0.png

Usually FRAMs don't take much current to operate.  Can you use a PSoC output pin as the VDD for the FRAM in your design?  If so, you can define a initial condition of 'Low' for the output pin at reset.  This should guarantee the FRAM to be power reset on any CPU reset.

Len

PS:  If you use the VDD_FRAM pin idea above, make sure the SW initial IO configuration for the pin is set t o Strong Drive initial state 0.  This is to allow for a quicker reset of the FRAM to the power up state because a pulled-up SDA or SCL can parasitically power the VDD_FRAM if the PSoC pin controlling VDD_FRAM is set to Analog  Hi-Z.

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

5 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

KyTr,

Take a look at your configuration page tab "Reset" for your SDA and SCL pins.  It should look like:

pastedImage_0.png

Try changing it to Power-On Reset: Pulled-Up.

It might be that the MiniProg3 asserts the XRES line during a debugger reset but leaving the PSoC in a initialization debug state where your assignments in your TopDesign don't get loaded yet.  If you get this issue, if you select "F5" (Run all) in the debug mode, do SDL and SCL resolved themselves?  If so, it appears the MiniProg3 is halting before SW IO initialization. 

It is my understanding that "Power-On Reset:" is a non-volatile register setting designed to be invoked at initial HW reset whereas the settings in the "Pins" tab is for later SW initialization phase just before entering main().

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Len,

Thanks for the tip, I had actually completely forgotten that setting exists.  Unfortunately I don't think that's the ticket for this specific case.  High-Z (the hardware default) should actually be exactly what I'm looking for, as I would want the bus to be "released" on bootup.  The problem arises when the FRAM is holding SDA low in the case of the PSoC getting reset from the debugger in the middle of an I2C transaction

This can occur when code begins running after the first reset to begin attaching the Miniprog, but the debugger has not yet attached itself to the target.  The code then resets again (possibly during an I2C bus action) and the debugger is attached, but SDA is now being held low, presumably waiting for the next edge of the clock.  What I need to do is on startup, ensure that the bus is initialized to default.  I had thought asserting a stop condition would get the bus back to idle but it doesn't seem to work.

Putting a 1 second delay in code before initializing the I2C seems to buy enough time for the reset sequence to attach the debugger without the code running into the I2C transactions that are causing the problem.

0 Likes

KyTr,

Got it.  The FRAM was in the middle of a SDA out and the clocks stopped coming in (because the I2C master reset) to clock the remaining data out of the FRAM (read op).  I'd be more concerned with a partial write to FRAM.  Are you using a checksum or CRC with your data?

What FRAM are you using?

I spotted this at https://i2c.info/i2c-bus-specificationhttp://

pastedImage_0.png

Usually FRAMs don't take much current to operate.  Can you use a PSoC output pin as the VDD for the FRAM in your design?  If so, you can define a initial condition of 'Low' for the output pin at reset.  This should guarantee the FRAM to be power reset on any CPU reset.

Len

PS:  If you use the VDD_FRAM pin idea above, make sure the SW initial IO configuration for the pin is set t o Strong Drive initial state 0.  This is to allow for a quicker reset of the FRAM to the power up state because a pulled-up SDA or SCL can parasitically power the VDD_FRAM if the PSoC pin controlling VDD_FRAM is set to Analog  Hi-Z.

Len
"Engineering is an Art. The Art of Compromise."

Len,

I'm using a FM24C16B

Controlling the power to the FRAM is not a bad idea, Maximum current w/ SCL @ 1MHz is only 400uA.  I may request having control of the FRAM VDD on the if/when we revise this PCB.

Fortunately this only place this specific situation occurs is during FRAM reads (reading configuration information at startup) so nothing is getting corrupted, just getting some funky unexpected bytes on the read when it happens, throwing off system behavior (making debugging difficult when I need to test loading configs with the debugger attached).  On normal power up (not debugging) there is no issue.

I suppose a corrupted write could happen if there was suddenly a reset of the PSoC in the middle of an I2C transaction, but I have much bigger problems if the PSoC is randomly resetting in that way lol.  Even then, bytes will only get written on this FRAM upon receiving an entire data byte, if transmission is interrupted midway through a byte, the byte will not be written.

Might be a good idea to write a CRC into the FRAM though, I'm already calculating CRC when this config data comes in over serial, so writing it to FRAM as well wouldn't be much trouble.

0 Likes

KyTr,

A checksum is easier and quicker to implement.  In that case, I would recommend a 4 byte checksum.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes