Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC18's I2C bug

Status
Not open for further replies.

Oznog

Active Member
I have PIC18 with the C0 revision. There is a known errata sheet which says there was a bug where the BufferFull flag could clear accidentally, leaving the I2C code stalled.

I think I'm seeing it in practice. The bus gets frozen, and I know it's in the slave, since I can reset the master and it remains frozen. The system was designed so that the slave goes to sleep when there are no I2C requests (possibly for weeks), so unfortunately there's no way to discerne when the master has no requests if the bug happens at the start of pkt. If it happens during the pkt, I could do a timeout, but this isn't always the case.

Any ideas? My only idea now is to change SLEEP to a specific write command, but I didn't implement the I2C write functionality on either the master or slave and would rather not develop & verify it for just this single command. Could I read the SCK, SDI pins once the I2C bus times out to determine if it's a case of a bug & a stuck bus rather than an proper case of an idle I2C bus?

Why the hell did Microchip let such a crappy part out? This was already their "fix" for the B-revision.
 
Hey, I think I have a solution which is better than Microchip's.

Microchip suggests trying to reset the i2c slave when a counter used as a watchdog expires. There is NO specified, guaranteed way to reset the I2C and it's guaranteed to corrupt the pkt in progress. But I found this works dandy:
1. Inside the I2C interrupt routine, change any reference to BF to (BF||BF_fix). Clear BF_fix in the routine in which it is used no matter what happens.
2. It turns out the I2C pins can be read ok. I was hoping this would work, it is not explicitly stated in the spec. So the watchdog first checks that the SDA or SCK line is low, indicating the bus is still in use.
3. If the timer's expired and SDA or SCK is low, set BF_fix=1 and manually set SSPIF=1. This will force the ISR to resume and make up for the lost BF_fix.

Looks pretty flawless, as long as the master's guaranteed to send data pkts faster than the watchdog. If not, we have a problem.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top