Having problems with I2C error checking,

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

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hi,

   

I’ve been working on I2C communication between a PSOC 5LP (master) and multiple PSOC 4’s (slaves). This is being done with a Cy8CKIT-059 and multiple Cy8CKIT-049-42xx boards. The goal is to be able to add a slave device to the bus, in a default configuration with address 0x08, and have the master assign it a new address and maintain a list of all currently used slave addresses. The slave stores its address in flash (Emulated EEPROM) so at power up the configuration remains unchanged. For now, the part about having the master store a list of addresses has been set aside and I’m just sending commands through USBUART via a terminal.

   

Most of this project is functioning correctly, but I’m running into a few hiccups that really come down to error checking. There are also some parts of the code that aren’t exactly elegant, but thus far my goal has been to just get things working, so please excuse them. I have attached a zip with the main.c and main.h for both the master and slave. My questions are:

   

 

   

1. I am using the I2CMasterWriteBuf and I2CMasterReadBuf API functions and they are working well. My problem is that these API functions are returning “SCB_I2C_MSTR_NO_ERROR” when they try to talk to a slave address that does not exist. I am clearly not understanding how the return value of the functions is created and would like to be able to find out if a slave is not on the bus and generate an error.

   

 

   

2. The second concern is regarding sending a save device a command to change its address. I am currently using a simple block check to validate packets, which is working as expected. I would like to find a way to generate some kind of acknowledgement from a slave saying that the incoming packet is valid before executing its address change. This way the master knows the packet was received correctly and can update its slave address array accordingly.

   

As of now if the block check isn’t correct the slave will not attempt to update its address, but the master has no way of knowing that this did not happen. The only way I can do this right now is to attempt to read from the new slave address and see if the correct status value is returned, indicating a successful address change, though if the address isn’t there I run into the previous problem. This can be worked around by checking that the status in the returned packet is correct, but it feels a bit like going around my elbow to get to my rear and, frankly, I don’t really like it.

   

I’m currently using the MasterWriteBuf and MasterReadBuf functions with the mode set to “MODE_COMPLETE_XFER” which I have a hunch is part of the problem. I feel like I need to use the “MODE_NO_STOP” mode, but I don’t understand how this works and can’t seem to get things working with it.

   

 

   

 

   

I’m new to Cypress devices as well as I2C. Any help with understanding where my logic is incorrect or guidance to a solution would be greatly appreciated. If anything isn’t clear I’ll be happy to try and resolve any ambiguity.

   

 

   

Thanks,

   

Matthew

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

Welcome in the forum, Matthew.

   

Divide the communications with the slaves into "Transactions" which usually is a write (command) followed by a read (results). Keeping this together the “MODE_NO_STOP” is needed for the write part and a “MODE_REPEAT_START” are needed for reading the response.

   

Checking for a slave on a given address is best done using I2C_MasterSendStart() followed by a MasterSendStop() and inspecting the returned results for errors.

   

To be on the safe side you could use something like a first-time verify after an address change and a fall-back when the master does not call for that. Do not spend much time within a transaction because that blocks the bus. Write to flash takes a considerable time, so do that outside a transaction, While write to flash interrupts might be disabled for a few ms.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Bob,

   

Thank you very much for the info, and sorry it's taken me so long to respond. The slave check using I2C_MasterSendStart() ad I2C_MasterSendStop() worked like a charm after I figured out how to use them, so thank you. I've not been able to figure out the "Transactions" as you described them for my case, but using the previously mentioned approach does seem to meet my requirements. So thanks again!

   

~Matthew

0 Likes