I2C_MasterWriteByte()

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

cross mob
Anonymous
Not applicable

I have discovered that procedure I2C_MasterWriteByte() only returns if an ACK is received otherwise it hangs forever.  This doesn't seem right.  I know the component data sheet says this function is blocking and does not exit until the byte_complete bit is set in the I2C_CSR register.  But the description of this register states this bit indicates that eight bits of data plus ACK/NAK.

0 Likes
1 Solution
Anonymous
Not applicable

Hi Stan,

   

 

   

As Bob Marlowe has already suggested, it is advisable to check the status of I2C_MasterSendStart(). If this function has failed, then any further attempt to Write a byte will be unsuccessful.

   

 

   

Is it possible for you to upload the project here, or atleast the code snippet involving the I2C communication so that we can find out if there is any issue in the code implememtation.

   

 

   

By the way, I am assuming that there are no issues with the hardware setup (the SCL and SDA pins are configured as Open Drain Drive Low, and pulled up using external resistors).

View solution in original post

0 Likes
27 Replies
Anonymous
Not applicable

Hi Stan,

   

 

   

As you have mentioned, I2C_MasterWriteByte() is a blocking statement which doesn't return till the I2C Slave ACKs or NACKs the Byte Write command. Here are some of the questions which will help in narrowing down to the cause of the issue you are facing:

   

 

   

1) Is the Start / Restart regerated explicitly before using this API? Without a valid Start / Restart, this API is not functional.

   

2) Are there External Pull-up Resistors on the SCL and SDA lines?

   

3) Are you able to see the returned status of the I2C_MasterWriteByte() API in debug mode? It contains the status of the operation.

   

 

   

Regards,

   

Gautam Das

0 Likes
Anonymous
Not applicable

The returned value will be:

   

 

   

0: If the Byte Write was complete without any error.

   

2: If the Master is not the Valid master on the bus.

   

3: If the last byte was NAKed.

   

4: If the Master has lost arbitration.

0 Likes
Anonymous
Not applicable

The problem is I2C_MasterWriteByte() does not return.  I found this when I wasn't checking the return value of routine I2C_1_MasterSendStart() before calling I2C_MasterWriteByte().  But it still doesn't seem correct that I2C_MasterWriteByte() does not return.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

MasterWriteByte() IS blocking. So you'll have to check first, if the slave is addressable. That's what the MasterSendStart() is for. You have to check the result of that function whether it is appropiate to issue the MasterWriteByte() call.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hi Stan,

   

 

   

As Bob Marlowe has already suggested, it is advisable to check the status of I2C_MasterSendStart(). If this function has failed, then any further attempt to Write a byte will be unsuccessful.

   

 

   

Is it possible for you to upload the project here, or atleast the code snippet involving the I2C communication so that we can find out if there is any issue in the code implememtation.

   

 

   

By the way, I am assuming that there are no issues with the hardware setup (the SCL and SDA pins are configured as Open Drain Drive Low, and pulled up using external resistors).

0 Likes
lock attach
Attachments are accessible only for community members.
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Some useful information, attached.

   

 

   

Regards, Dana.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Prior post was largely PSOC 1 material, but does have bus loading graphs.

   

 

   

Here is a method to compute pullup values -

   

 

   

   

 

   

Regards,. Dana.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

0 Likes
lock attach
Attachments are accessible only for community members.
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Attached.

0 Likes
Anonymous
Not applicable

I do understand that the call to I2C_MasterWriteByte() is blocking waiting for an ACK or NAK.  I also understand that I should check the returned result of I2C_MasterSendStart() which I now do.  So far I have not encountered a problem with I2C_MasterWriteByte() but it still seems like I2C_MasterWriteByte() should always return because a no response from the addressed device is a NAK, at least that's my understanding.  So if I2C_MasterWriteByte() does not ever return what's it waiting for?  Perhaps this is a none problem if the result of I2C_MasterSendStart() is always checked before calling I2C_MasterWriteByte().

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

A NAK is not the absence of a reply, it is a defined signal returned.

   

 

   

And to check the result of MasterSendStart() is quite usual, what else is the returncode good for.

   

 

   

Neither receiving an ACK nor a NAK is an errorneous condition. There is NO timeout defined for the I2C protocol, so there is no choice for the MasterWriteByte() as to wait infinetively (or power down).

   

 

   

Bob

0 Likes
GrRa_284656
Level 2
Level 2
5 sign-ins 10 replies posted 5 replies posted

Dear Bob,

   

I'm having very large, big problems with the use of MasterWriteByte() and the I2C Master Fixed Function

   

I cannot use I2C Master UDB: I've no space in the chip.

   


The MasterWriteByte hangs forever as Stan introduced you to the forum.

Instead, it would seem that the implementation UDB functions perfectly.

Tomorrow I will try to do specific tests with the UDB implementation  to check whether the MasterWriteByte() crashes if it not receives ACK.

But anyway I do not understand (and anyway I cannot use UDB in the product, and anyway I paied for the Fixed Function silicon also 😉

   

Point 1 I don't understand

   

-----------------------------------
When the I2C Master sends the ninth clock pulse (and it has to send, it is the Master that generates it):
- If the Slave holds low the bus --> ACK
- If the Slave releases the bus (H) i --> NAK.

What should wait for the I2C_MasterWriteByte ()??

   

 

   

Point 2 I don't understand

   

-----------------------------------

   

You say it is necessary to use the returned status of  I2C_MasterSendStart()  to see if the chip has connected I2C Slaves. If the returned status is positive then we can send the I2C_MasterWriteByte ().
(tomorrow I'll try to do it)
But if the last sentence of your post is correct "Neither receiving an ACK nor NAK is an errorneous condition. There is NO timeout defined for the I2C protocol, so there is no choice for the I2C_MasterWriteByte () as infinetively to wait (or power down). "

then ... in the case of I2C communication problems, it should also block the I2C_SendStart()? It should also SensStart wait endlessly for the ACK or NAK I2C address???

   

 

   

Thank you for your collaboration Bob and thank to Stan (and excuse me for my english 😉

   

Tomorrow I am on this problem and I will try to debug perfectly the FF I2C (psoc5LP, 66MHz clock)

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

I have got a logic-analyzer that is able to decode I2C-communications. That part has helped me out of some troubles!!!

   

When you own something similar it will be easy to find the bug. What is the slave-device you are communicating with?

   

Are you located in the EU? If so, there is a cheap solution for the logic analyzer: www.ikalogic.com/

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
GrRa_284656
Level 2
Level 2
5 sign-ins 10 replies posted 5 replies posted

Dear Bob,

   

I have a very nice scope (I've also the ikalogic 😉

   

 

   

As you see in the attached jpeg, also I2C_SendStart() hangs forever in the case of erroneus I2C address (I2CAdd=0x00)

   

The SDA on the 9th clock pulse is high (NAK).

   

But the i2C_SendStart hangs forever.

   

 

   

There is no way with I2C_SendStart() to solve the problem regarding I2C_MasterWriteByte().

   

Graziano

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

When Cypress programmed the I2C modules they strongly clinged to the specifications. That means: no timeout.

   

When you are really in need you may change the API and introduce a timeout.

   

Did you try the same with a multi-master I2C ?

   

 

   

Bob

0 Likes
Anonymous
Not applicable

I have a related problem with I2C implemented as UDB and the use of the low level functions.

   

In my case, two things happen, one is that MasterReadByte actually reads two bytes from the

   

bus, which is not supported by our target which returns a NAK.

   

The later STOP either is not really generated or at least not recogized by our device and

   

hence the bus hangs forever.

   

Unfortunately, the UDB implementation of I2C is not completely documented.

   

Where is the register "I2C_1_GO_REG" defined? It is used in I2C_1.h (or however the generated file is called),

   

but it is not documented in the component data sheet (I2C_v3_30).

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

In my applications the MasterReadByte() always reads one (1) byte, never more than that. Can you 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 (do NOT use chrome, that still may not work).

   

 

   

Bob
 

0 Likes
Anonymous
Not applicable

Ok, found the problem.

   

I missed that the last byte should be received with a negative ack.

   

This is not explained in the function description but only below in the example.

   

 

   

Andreas

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Heureka! Took you a long way obviously. Fine that it works at last!

   

 

   

Bob

0 Likes
Anonymous
Not applicable

 NONE of the API calls should ever block forever. It is entirely conceivable that the part may be addressible but be malfunctioning, and now your design fails because you can't time out.

   


I've rewritten a number of "core" API functions with simple timeouts to prevent this possibility. Blocking forever is never a good way to handle things in an embedded space.

0 Likes
Anonymous
Not applicable

I've found an interesting problem - I have a design with a LED port, a clock source, and 3 I2C blocks, all UDB implementation, all use the same clock source (6.4Mhz).

   

One of them seems to work fine - the other two don't - it takes them about 55 seconds to come back from a MasterStart operation.  I toggle LEDs to mark my location in code.

   

Anyone else see this?

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Never seen that, can you 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
Anonymous
Not applicable

Much of Cypress's code 'just' hangs if it encounters a bit that doesn't flip - it is why you have to re-write the I2C code and any of the SPC interfaces (cyspc/cyflash), or you can spend days thinking your design is wrong.

   

 

   

With Cypress's code, first assume it is hung up in an infinate loop - then, and only then debug your hardware.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Again: The I2C protocol as defined by Philips in 1982 nor the last version v5 did specify any timeouts. This is a commonly known flaw in the definitions of I2C and is not related to the Cypress implementation. So when any company writes an approved I2C driver there may not be any timeouts or the approvement would fail.

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

@RickyRock, would you mind filing a CASE on the MasterStart delay issue.

   

I cannot speak for Cypress but i am sure they would be grateful.

   

 

   

I ran into a problem with I2C that if pullups "opened" the buss would hang

   

the part, also a I2C Phillips oversight. So I filed a CASE to inform Cypress

   

team as an issue like this is potentially harmful to designs concerning safety.

   

 

   

Lastly consider letting forum know results.

   

 

   

    

   

          

   

To create a technical or issue case at Cypress -

   

 

   

www.cypress.com

   

“Support”

   

“Technical Support”

   

“Create a Case”

   

 

   

You have to be registered on Cypress web site first.

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

@bob -- that's a pretty weak argument, but I guess it's a technicality.

   

 

   

As I mentioned, I rewrote some of the core drivers to have explicit timeouts. I also recently noticed that the I2C primitives have a bus monitor that would time out and force the transaction to terminate but it doesn't appear to be enabled by default. It's certainly not exposed to the normal user.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Is that a register configuration user can get to, or is it completely

   

out of user access ? If former we ought let the community know.

   

 

   

Regards, Dana.

0 Likes