Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PIC]: F877 I2C module

20 views
Skip to first unread message

Alan B. Pearce

unread,
Sep 11, 2002, 5:41:43 AM9/11/02
to PIC...@mitvma.counterspam.mit.edu
Back in August Olin wrote

>3 - The MSSP module does not directly support slave flow control
>during a write. The master can always slow down communications to
>avoid being overrun of underrun because it controls the clock. A
>slave during a read sequence can (automatically does) do clock stretch
>to avoid underrun. However, there is nothing a slave can do to avoid
>overrun during a write, at least not directly using just the IIC bus
>via the MSSP.

Is this correct? I understood that a slave can avoid overrun during a write
by clock stretching the acknowledge bit. Using the code from AN734 (Slave
I2C using SSP) this is what I see happening on the I2C bus, because it
collects the byte out of SSPBUF before releasing the clock for the ACK.

I came across this while going through my archive of mails which I squirrel
away as useful potential problem solvers.

The problem I have is the slave device seems to hold the clock low after a
read of a byte. I suspect that what I see may be corrected by applying what
Olin says below, though I doubt it for reasons I give after the quote.

>2 - Note that a slave in clock stretch mode holds SDA according to
>the high bit of SSPBUF. When the SSPCON,CKP is set to release clock
>stretch, clock is released immediately. While this makes sense, the
>fix to #1 can cause trouble here at high CPU clock speeds (has nothing
>to do with IIC clock speed). The fix for #1 slows down SDA a little
>with respect to SCL. With a 20MHz slave, one instruction is not enough
>time to start driving SDA appropriately before clock is released. This
>can cause the high bit of the data byte to be read as 0 by the master
>when it 1 inside the slave. The fix is to set SSPBUF a few instructions
>before setting SSPCON,CKP. Insert a few NOPs if necessary.

First my clock rate is much slower, the PIC is clocked at 3.6MHz, and the
I2C is currently running at about 50KHz. The I2C clock rate was run at this
speed for other problems which have now been resolved, and has not yet been
put back to 100kHz. Both devices are 16F876's. The master device writes and
reads some EEPROM chips and DAC chips satisfactorily on the I2C bus, so I
believe the code in this is satisfactory.

From reading the AN734, it would seem that once the byte is put in the
buffer of the slave for transfer to the master, everything should be
automatic for the data to transfer and the NAK to be generated by the
master, once the slave releases the clock. I see the eight clock pulses for
the data, but the clock for the ACK never occurs. The other thing that
puzzles me is that the byte that is supposed to be transmitted is 01, but
what I see on the I2C bus is 00, and the bus never gets released after the
eight clock pulses. Has anyone else had to deal with a problem like this,
and give an idea of the remedy?

TIA

--
http://www.piclist.com hint: The PICList is archived three different
ways. See http://www.piclist.com/#archives for details.


Jason Harper

unread,
Sep 11, 2002, 6:47:16 AM9/11/02
to PIC...@mitvma.we.hate.sp.am.mit.edu
"Alan B. Pearce" <A.B.P...@RL.NoSpam.AC.UK> wrote:
> From reading the AN734, it would seem that once the byte is put in the
> buffer of the slave for transfer to the master, everything should be
> automatic for the data to transfer and the NAK to be generated by the
> master, once the slave releases the clock. I see the eight clock pulses
for
> the data, but the clock for the ACK never occurs.

The data transfer is automatic, the NACK/ACK isn't - how would the master
know which of the two you wanted to send? You have to set or clear ACKDT
as desired, and then set ACKEN (both in SSPCON2) at the master side for the
9th bit to be transferred.
Jason Harper

Alan B. Pearce

unread,
Sep 11, 2002, 7:44:37 AM9/11/02
to PIC...@mitvma.delete.mit.edu
>The data transfer is automatic, the NACK/ACK isn't - how would the master
>know which of the two you wanted to send? You have to set or clear ACKDT
>as desired, and then set ACKEN (both in SSPCON2) at the master side for the
>9th bit to be transferred.

Yes I appreciate that, and the code in the master is working correctly.

However on digging somewhat deeper into what is happening in the slave
device which is where the malfunction happens, I find that somehow the TRIS
bit for the SDA line is getting set to output, and the port bit is set to 0
:))))

The TRIS bit is getting changed somehow while another couple of pins are
having their tris bits changed to change direction, and it is occurring
during an independent operation. Most of the time the code is working
because the I2C is not being accessed during the critical times, so the
problem is not seen.

Now I just have to work out precisely which instructions sure misbehaving.
:))

Olin Lathrop

unread,
Sep 11, 2002, 8:22:27 AM9/11/02
to PIC...@mitvma.nothis.mit.edu
> Back in August Olin wrote
>
> >3 - The MSSP module does not directly support slave flow control
> >during a write. The master can always slow down communications to
> >avoid being overrun of underrun because it controls the clock. A
> >slave during a read sequence can (automatically does) do clock stretch
> >to avoid underrun. However, there is nothing a slave can do to avoid
> >overrun during a write, at least not directly using just the IIC bus
> >via the MSSP.
>
> Is this correct?

Nah, I just made it up. August was a slow month.

> I understood that a slave can avoid overrun during a write
> by clock stretching the acknowledge bit.

No, it can't.

> The problem I have is the slave device seems to hold the clock low after a
> read of a byte.

Right. Like I said, the MSSP does clock stretch on a read, but not on a
write. Therefore after a read transfer, the slave will hold clock low until
SSPCON,CKP is set to release it.

> >2 - Note that a slave in clock stretch mode holds SDA according to
> >the high bit of SSPBUF. When the SSPCON,CKP is set to release clock
> >stretch, clock is released immediately. While this makes sense, the
> >fix to #1 can cause trouble here at high CPU clock speeds (has nothing
> >to do with IIC clock speed). The fix for #1 slows down SDA a little
> >with respect to SCL. With a 20MHz slave, one instruction is not enough
> >time to start driving SDA appropriately before clock is released. This
> >can cause the high bit of the data byte to be read as 0 by the master
> >when it 1 inside the slave. The fix is to set SSPBUF a few instructions
> >before setting SSPCON,CKP. Insert a few NOPs if necessary.
>
> First my clock rate is much slower, the PIC is clocked at 3.6MHz,

That means you have a minimum of 1.1uS between setting SSPBUF and releasing
the clock by setting SSPCON,CKP. This is fine as long as your worst case
SDA rise time is less than 1.1uS. If not, insert NOPs to increase the delay
between SDA being set to the new value and SCL released.

> and the I2C is currently running at about 50KHz.

This has nothing to do with the problem above, which is a function of SDA
rise time, not bus clock speed. Of course the maximum SDA and SCL rise
times do dictate the upper limit of the clock speed.

> From reading the AN734,

Personally I don't find the Microchip app notes of much use. It is much
more important to read the data sheet very carefully. You probably need to
read the MSSP chapter and IIC section several times.

> it would seem that once the byte is put in the
> buffer of the slave for transfer to the master, everything should be
> automatic for the data to transfer and the NAK to be generated by the
> master, once the slave releases the clock.

Not quite. First the master must be tring to do a read, else the clock
pulses will never be generated whether the slave releases the clock or not.
Second the master does not automatically generate ACK or NACK. This must be
done separately by the master code after the byte is received. It sets
SSPCON2,ACKDT to select ACK or NACK, then sets SSPCON2,ACKEN to start the
ACK/NACK sequence. You really need to read the data sheet, screw the app
notes.

> I see the eight clock pulses for
> the data, but the clock for the ACK never occurs.

That is consistant with your misconception above.

> The other thing that
> puzzles me is that the byte that is supposed to be transmitted is 01, but
> what I see on the I2C bus is 00, and the bus never gets released after the
> eight clock pulses. Has anyone else had to deal with a problem like this,
> and give an idea of the remedy?

Strange and undocumented things can happen when a slave is overrun on a
write, but it seems you are having problems with reading.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

Jason Harper

unread,
Sep 11, 2002, 9:53:59 AM9/11/02
to PIC...@mitvma.cut.mit.edu
"Alan B. Pearce" <A.B.P...@RL.RemovE.AC.UK> wrote:
> The TRIS bit is getting changed somehow while another couple of pins are
> having their tris bits changed to change direction

Let me guess, you used BSF or BCF on TRISC? There is a problem with
read-modify-write instructions on the TRIS registers with certain
peripherals active. TRISC<3:4> have to be inputs (1) for the SSP module to
work, however if you do an RMW operation to TRISC at a moment when the SSP
module is using one of those pins as an output, the bit will read as a 0,
and get written back as a 0. See section 3.3 of the 16F877 datasheet.
Jason Harper

Alan B. Pearce

unread,
Sep 11, 2002, 11:58:16 AM9/11/02
to PIC...@mitvma.spammers.are.scum.mit.edu
>Let me guess, you used BSF or BCF on TRISC? There is a problem with
>read-modify-write instructions on the TRIS registers with certain
>peripherals active. TRISC<3:4> have to be inputs (1) for the SSP module to
>work, however if you do an RMW operation to TRISC at a moment when the SSP
>module is using one of those pins as an output, the bit will read as a 0,
>and get written back as a 0. See section 3.3 of the 16F877 datasheet.

yeah that is exactly what I am doing, and had come to the same conclusion
from what I was seeing as the problem. I am going to modify the hardware to
move the lines that need their direction changing to port A (port B is
already fully in use). I hadn't appreciated the dirty way they deal with the
TRIS register, while the data register is properly multiplexed. talk about
spoil the unit for a ha'porth of tar :))

0 new messages