??? 03/04/04 14:18 Read: times |
#65932 - RE: LPC932 with simple I2C peripherals Responding to: ???'s previous message |
Ok, For the PCF8563 I found basically that I needed to do the following things from my initial implementation to get it to behave.
The initial implementation is a software bit banged scheme connected to a 'GP32 microcontroller. I had made the driver to generate I2C waveforms at right near the datasheet timing parameters. I also made a layer of access routines to access the RTC chip a register at a time for either a write cycle or a read cycle at a time. This made random access in higher level routines easier. IE for writing access the register to stop the clock and then write HH or whatever in the order that is convenient. The apparent problem was that the RTC would hiccup once in a while and not perform an ACK on a byte transfer if the byte transfer was interrupted in the middle by a timer interrupt that I have elsewhere in the code that pops every 1 millisecond and lasts for 270 microseconds. (This timer ISR processes some periodic activities including managing the output of some 100 Hz pulses, filtering the A/D readings from four sources, scanning a 2x3 keypad, and controlling a PID loop wherein software performs the regulator part of a voltage booster circuit by controlling the on/off pulses to a MOSFET in a switching circuit). This product has a remote serial port used for testing of the device and we were noticing that the faulty reads of the RTC were happening as an attached PC would request a read of the MMDDYY and HHMMSS values from the chip. I traced it to the RTC failing to acknowledge a transfer when that transfer had been interrupted in the middle like I noted above. The faulty reads initially were only occurring on about 1 in 300 attempts to read the RTC. Through the investigation of the problem I made a series of changes to see if I could improve the reliability of reading the clock. As each change was made the incidence of the faulty read would go down till I got to just before the final step wherein it would still fail about once in 4000 reads. After the final correction I was able to read the RTC a million times without any errors. First off I added NOPs into the bitbang routines to slow down the nominal I2C sequence from right at data sheet speed to about 1/2 data sheet speed. Next I added checks whereever the software tried to let the SCL line go high I polled the SCL input to ensure that the SCL was actually high before stepping forward. I re-arranged the interrupt logic in the program a bit and fixed up the low level byte transfers of the bit bang routines so that and start sequence, stop sequence, or 9 clock byte/ack sequence would complete with interrupts disabled. Finally I changed the clock reading and writing procedure such that instead of accessing the RTC one register at a time I took advantage of the block mode and did read/write of the necessary registers in a group within one I2C command sequence. Of course in this type of investigation, after getting the RTC to behave properly, I did not go back and take out changes made at the earlier steps to see if they were absolutely necessary. It seemed OK because overall the block mode is way more efficient anyway than trying to access the RTC a byte at a time through a whole series of single byte read/write accesses. Some astute reader who knows this chip might ask how I managed the time byte concurrency issue while I was using the single byte read method. That was handled at a higher level as the reads were done I was reading out the SS-MM-HH DD-MM-YY and then reading SS again. If SS had changed then repeat the whole read process. In the new block read process this re-reading step is wholly unnecessary as per the design of the RTC chip and "hinted at" in the data sheet. I tried it and the RTC chip latches all read values at the start of a single I2C transfer sequence. A note in the data sheet says that you have to complete the whole I2C transaction START TO START within 1 second (whatever that really means). This latter point seems to fit the block reading senario. On the other hand I think that the problem I was seeing stemmed from the RTC getting a single byte read sequence that was then interrupted by my long timer interrupt and then the 1 second update in the RTC would kick in. Apparently this causes some upset in the internal state machine inside the RTC to cause it to fail to ACK some following byte in the part of the transfer sequence that was in process and had been interrupted. Without a chip schematic and detailed internal operational definition one can never really be sure of what was actually going on in the chip. It seems that Philips had intended for the readout to use the block mode and when I did it that way it seems to work properly. Michael Karas |