I2C Slave not respecting NACK and STOP?

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.
kemic_264446
Level 4
Level 4
First like received
        I have an I2C Component in my design, using Fixed Function block at 100kHz speed. It is set in slave mode and initialized with a buffer of 250 Bytes. The bytes in the buffer are all initialized with the values 0 to 249 to make debugging easier. When my master (an external processor) READS from the slave it reads only 240 bytes from the buffer. The reads are all present and correct, and the master NACKs the last byte and performs a proper I2C Stop sequence. In my Creator project I poll using I2C_SlaveStatus() and look for the I2C_SSTAT_RD_CMPLT flag. In my handler when I see I2C_SSTAT_RD_CMPLT I reset the buffer using I2C_SlaveClearReadBuf(); The problem is that this flag doesn't get set after each read from the master, it only gets set after every 4 or 5 reads, and the slave continues reading through the buffer instead. (Returning 0xff once it overflows). I have used a logic analyzer to look at the data and it decodes it as valid I2C with the correct timings and sequences. Attached are 2 screen shots from my logic analyzer showing the end of the 1st 240 byte read and the start of the next read (which should have reset to the start of the buffer). Any ideas as to why this should be behaving like this? I cannot attach the whole project as large parts of it are under NDA to my client. I will try to make a smaller project with just the I2C to show the problem.   
0 Likes
4 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

This sounds very strange and althoug I've done some designs with I2C I've never seen something similar.

   

I'm afraid you have to break down your project to the pure I2C-communication.

   

Ah... try to use I2C_SlaveClearReadStatus() instead

   

 

   

Bob

0 Likes
kemic_264446
Level 4
Level 4
First like received

 Hi Bob

   

 

   

Thanks for the reply.

   

Turns out it was the slew rate on the microchip PIC that the PSoC was trying to chat to. In the logic analyzer it looked great, but on the oscilloscope I soon saw a problem. The PSoC wasn't actually seeing the stop sequence. What looked nice and square on the logic analyzer were actually well rounded peaks on the 'scope. The pull ups are 4.7K and cannot be changed at this time.

   

Anyway, what I did was switch them round - the PSoC is now master, the PIC is slave, so the PSoC is driving the bus and it works great. I've even been able to get better throughput. Clock stretching works a treat also! Ka-ching!

   

This particular board has loads of I2C on it - 4 Audio processors, 2 NVRAM and the PIC all on I2C buses. The PIC does Ethernet offloading for me. Since I2C SLAVE on the pic has to be interrupt driven it even makes the ethernet throughput a bit better - we are not blocked while doing I2C writes and reads for as long as we were in master mode.

   

Cheers!

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

In case you want/need to swap master and slave again, you might use a I2C bus buffer to get better signals. E.g. one from Linear Technologies: http://parametric.linear.com/i2c_and_smbus_bus_buffers_and_accelerators

0 Likes
kemic_264446
Level 4
Level 4
First like received

 Thanks thats a good bit of advice.

   

In this case the board already exists (in their 1,000's) so a change to the PCB was not possible.

0 Likes