0
\$\begingroup\$

I've written a set of "bit-bang" software routines for the PIC18F2620 device. These routines work well for reading and writing 24LC256 EEPROM and DS1307 RTCC devices for the most part. (I wrote this set of routines after spending a hair-tearing week trying to get C18 HW I2C to consistently work).

I am now writing verification (V&V) tests for this set of routines and am experiencing intermittent failures when writing longer sequences of data to the 24LC256 (> 40 bytes). My system has a 2mSec timer running (TIMER0) high priority, and a USART receive interrupt on low priority. I am beginning to suspect that the TIMER0 interrupt is leaving a Master-write sequence hanging too long during an interrupt, and the slave 24LC256 is giving up. Since there is no such thing as clock stretching for the master I believe I may have to start disabling interrupts during Master I2C transactions (from I2C_Start through I2C_Stop). I am leary of writing code where an interrupt is disabled in one routine and with hopes that it will always be properly re-enabled in another routine. (kind of a malloc/free situation).

Before adding these enable-disable interrupt changes I want to ask if others in this forum have had to deal with similar situations, and how they were handled.

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Why risk missing data with bit-bang and interrupts? When you have a 400kbps UART ? google.com/… \$\endgroup\$
    – D.A.S.
    Commented Oct 17, 2019 at 22:09
  • \$\begingroup\$ Fair question, Tony. I struggled to implement HW I2C on the PIC-MSSP for about a week. I looked at maybe a dozen examples found through a Google search and every example seemed to have a glitch in some code. The datasheet errata for the PIC18F2620 indicates that this processor has numerous problems. My I2C devices were added late in the project. Had I known about the troublesome MSSP I would have chosen another processor (ARM Cortex M3 maybe)--but I'm stuck with this one now. If you know of some example code that works I'd gladly welcome seeing it. \$\endgroup\$
    – Doug12745
    Commented Oct 17, 2019 at 22:56
  • 1
    \$\begingroup\$ I have no more than the code in the link I gave, which must work as it is from the OEM You can squeeze a lot of bytes easily in 100kbps but your flow control and interrupt margin is unknown. Can a stack overflow? \$\endgroup\$
    – D.A.S.
    Commented Oct 17, 2019 at 23:18
  • 1
    \$\begingroup\$ As none of the slave devices are SMBUS devices so they do not require minimum clock. The PIC can delay as long as it wants at any point in the I2C transaction. What may be the problem is that when you run the I2C with a timer (why?) if one timer interrupt is delayed then the next interrupt might be already pending and comes too early so there is too little time between two interrupts. Have you debugged this in any way, such as oscilloscope or logic analyzer? \$\endgroup\$
    – Justme
    Commented Oct 17, 2019 at 23:53
  • \$\begingroup\$ @Doug12745 I've written a lot of PIC18F code over the years. (Haven't done so in years, though.) In the most recent case, I was doing both UART, fast ADC and DAC work, as well as handling I2C "bit banged" in the background using a timer. (I could go back and find the exact E^2 I was reading and writing with, but I don't think the work was much different than your case.) Zero problems. (I used the timer at a faster rate than 2 ms, by the way.) The background I2C code used a state machine. It was relatively easy to write, too. I'm flummoxed that you are having trouble. \$\endgroup\$
    – jonk
    Commented Oct 18, 2019 at 0:15

1 Answer 1

1
\$\begingroup\$

Turns out that JustMe (thanks) pointed out that during an interrupt the I/O lines are held in their interrupted state. Since slave devices have no minimum clock time, the i2c interface essentially becomes frozen in time during the interrupt. Therefore interrupts should present no problems for bit-bang I2C code (assuming of course that the interrupt code does not interfere with the I2C port lines).

Also, in writing bit-bang, I2C code SSPCON1 should use the SSPM3:SSPM0 setting of 1011b (Firmware controlled Master mode) rather than the 1000b setting (Master mode clock). Setting SSPM3:SSPM0 to 1011b releases hardware control over the timing allowing the BB code to handle the clock timing. Turns out that I was using the wrong setting here. :(

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.