CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PIC24 I2C slave sometimes setting first data bit high?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
allenhuffman



Joined: 17 Jun 2019
Posts: 540
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PIC24 I2C slave sometimes setting first data bit high?
PostPosted: Wed Jul 24, 2024 10:18 am     Reply with quote

We have some well-tested I2C code that has been in use for years, but while trying something new, I observed something:

My Master program tries to read a few bytes from a PIC24 Slave device. Normally, we respond with a 0xAA (10101010) byte as a start code, followed by the rest of a header and then any data plus a checksum at the end.

Using a Saleae Logic Analyzer, and having the PIC24 return "0x01" for the first byte, shows this most of the time:


Good:

I see the correct clock pulses, and the Master writes out the address with the read bit set (0x65 in this case).

I then see the data line drop LOW until the next set of clock pulses to read the 0x01.

Bad:

I see the correct clock pulses, and the Master writes out the address with the read bit set (0x64).

I then see the data line remain HIGH. When the next set of clock pulses happen, it is still high and is seen as a "1" bit, then it drops and gets the "1" at the end, representing 0x81.

The PIC code is being done in an ISR, and I am manually clearing the IRQ so I can check for the P stop bit or IRQ for next incoming byte in my routine.

The code that is running in the ISR for this case ("first read") is basically this:

Code:
// Get a byte of data which is the address of the board.
i2c_read (SYSTEM_BUS); // NO CLOCK STRETCHING.
           
// Write out first data byte.
i2c_write (SYSTEM_BUS, 0x01);


In this case, this code runs when I am not expecting the Master to read (normally the Master writes a message as a command or request, and a buffer is prepared for the ISR to pull bytes from when the Master reads the response).

Has this "data line being held high" thing been observed elsewhere? We use several PIC24 variants, and I see this on a 24FJ64GA002. I have not checked our other boards.

If this happens during normal operation, we never "see" it because we use that 0xAA start code (10101010) so if a fake high bit is read, it still matches that code. Had we chosen 0x55 (01010101) then I bet we would have encountered this years ago.[/code]
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19336

View user's profile Send private message

PostPosted: Wed Jul 24, 2024 11:02 am     Reply with quote

I suspect that is caused by erratum 38.
The TBF bit is set, so the peripheral thinks it already has a byte to send,
which just happens to be 0xFF. Suggests some slight timing issue on the
bus is causing this error.
allenhuffman



Joined: 17 Jun 2019
Posts: 540
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Jul 24, 2024 11:17 am     Reply with quote

Ttelmah wrote:
I suspect that is caused by erratum 38.
The TBF bit is set, so the peripheral thinks it already has a byte to send,
which just happens to be 0xFF. Suggests some slight timing issue on the
bus is causing this error.


I see:
Quote:
The Transmit Buffer Full flag, TBF (I2CxSTAT<0>),
may not be cleared by hardware if a collision on
the I2C bus occurs before the first falling clock
edge during a transmission.


Any thoughts on what the source of a collision be? I am using the FTDI DLL on Windows and just telling it to:

Code:
ft4222Status = FT4222_I2CMaster_ReadEx (ftHandle,
    deviceAddress,
    START,
    &buffer[0],
    1,
    &sizeTransferred);


That causes it to write out the address and then do the read but NOT do the STOP at that time. The Saleae capture shows this sequence -- with over 504 uS before the operation.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
allenhuffman



Joined: 17 Jun 2019
Posts: 540
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Jul 24, 2024 12:10 pm     Reply with quote

As a workaround, I did a few tests. I found that if I just read one extra byte than what I really am expecting, the problem goes away.

The only thing special my code is doing is making a decision whether to write a byte from a transmit buffer, OR send a hard-coded "you read when I was not expecting it". That shouldn't have changed anything, unless that timing was enough to change the outcome.

Then I just tried enabling clock stretching on the address read, and that also made the problem seem to go away:

Code:
// Get a byte of data which is the address of the board.
i2c_read (SYSTEM_BUS, 2); // CLOCK STRETCH
           
// Write out first data byte.
i2c_write (SYSTEM_BUS, 0x01);


...so... maybe?
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19336

View user's profile Send private message

PostPosted: Wed Jul 24, 2024 12:21 pm     Reply with quote

That makes total sense.
What is happening, is that without the stretch, the master is intermittently
starting it's read _before_ the byte has been loaded. The clock must be
held till the byte is loaded.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group