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.
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.
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.
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.
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).
Prior post was largely PSOC 1 material, but does have bus loading graphs.
Here is a method to compute pullup values -
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().
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).
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)
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/
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().
i2c blocked on erroneous add.jpg 208.7 K