EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

I2C ReStart Vs. Stop-Start: SCL/DDL Hold

Started by Steve Auch-Schwelk July 22, 2004
I'm using the HCS12 and an AN2318 based iic driver, modified for GCC.

I seem to have some devices that don't like to be stop-started
between a Master-Write to Slave, and a Master-read from slave. But
the devices seem to work OK with a restart. Is there a difference
between restart and start that I should know about? What are the
advantages (lower wait time on SCL hold?)

I'm not sure that I have realy understood the ramifications of the
Frequency Divide Register, and it's SDA/SCL hold values. Do I need to
build in some delays in my driver to handle these, or does the
HCS12's IIC module do this automatically.

As an asside, I have found a number of holes in the code and
documentation of the AN2318, which I will publish here once I am
confident that I have the whole thing understood. Does anyone else
have experience with this?



Hi

Re:
> I'm using the HCS12 and an AN2318 based iic driver, modified for GCC.

I will be interested in the answer you receive, I have also written a driver based on cut down AN2318 example for MC9S12E128 running a 16MHz bus.
> I seem to have some devices that don't like to be stop-started
between a Master-Write to Slave, and a Master-read from slave. But
the devices seem to work OK with a restart. Is there a difference
between restart and start that I should know about? What are the
advantages (lower wait time on SCL hold?)
My driver has a marginal problem so that the IIC does not stop properly. I guess this could be the wrong timming parameters set.

> I'm not sure that I have realy understood the ramifications of the
Frequency Divide Register, and it's SDA/SCL hold values. Do I need to
build in some delays in my driver to handle these, or does the
HCS12's IIC module do this automatically.

I don't know how to set the dividers either. I would need to sit down for a long time with the IIC spec. which you can pick up from the philips website and work through it.
In anycase there is no need to add other delays. All philips and most other makers parts should take care of themselves. Some old style Xicor eeproms used to need extra delay of ~40mS whilst they were programming I seem to recall.

> As an asside, I have found a number of holes in the code and
documentation of the AN2318, .............. Does anyone else
have experience with this?

I cut my driver down to just a master. Andrew Lohmann AIIE
Design Engineer

PLEASE NOTE NEW EMAIL ADDRESS IS: Bellingham + Stanley Ltd.
Longfield Road, Tunbridge Wells, Kent, TN2 3EY, England.
Tel: +44 (0) 1892 500400
Fax: +44 (0) 1892 543115
Website: www.bs-ltd.com

------






> My driver has a marginal problem so that the IIC does not stop
properly. I guess this could be the wrong timming parameters set.
>

This could be one of the "bugs" I found in the driver code. When you
are master, and request a transmission from the slave which is < 2
bytes (ie 1 byte), you should immediately set the TXAK of the ibcr to
high (ie, no-ack signal), so that the slave knows to stop
transmitting. Acording to the documentation and the sample code, this
is only done when the 2nd to last bit is sent (which is never the
case with <2 bits).

I would have assumed that a STOP should sort this out, but it didn't
seem to.

--- In , "Andrew Lohmann's New Email Server"
<andrew.lohmann@b...> wrote:
> Hi
>
> Re:
> > I'm using the HCS12 and an AN2318 based iic driver, modified for
GCC.
>
> I will be interested in the answer you receive, I have also written
a driver based on cut down AN2318 example for MC9S12E128 running a
16MHz bus.
> > I seem to have some devices that don't like to be stop-started
> between a Master-Write to Slave, and a Master-read from slave.
But
> the devices seem to work OK with a restart. Is there a difference
> between restart and start that I should know about? What are the
> advantages (lower wait time on SCL hold?)
> My driver has a marginal problem so that the IIC does not stop
properly. I guess this could be the wrong timming parameters set.
>
> > I'm not sure that I have realy understood the ramifications of
the
> Frequency Divide Register, and it's SDA/SCL hold values. Do I
need to
> build in some delays in my driver to handle these, or does the
> HCS12's IIC module do this automatically.
>
> I don't know how to set the dividers either. I would need to sit
down for a long time with the IIC spec. which you can pick up from
the philips website and work through it.
> In anycase there is no need to add other delays. All philips and
most other makers parts should take care of themselves. Some old
style Xicor eeproms used to need extra delay of ~40mS whilst they
were programming I seem to recall.
>
> > As an asside, I have found a number of holes in the code and
> documentation of the AN2318, .............. Does anyone else
> have experience with this?
>
> I cut my driver down to just a master. > Andrew Lohmann AIIE
> Design Engineer
>
> PLEASE NOTE NEW EMAIL ADDRESS IS:
> andrew.lohmann@b...
>
> Bellingham + Stanley Ltd.
> Longfield Road, Tunbridge Wells, Kent, TN2 3EY, England.
> Tel: +44 (0) 1892 500400
> Fax: +44 (0) 1892 543115
> Website: www.bs-ltd.com >
>
> --------------------------------
----------
>
>





>
>
> > My driver has a marginal problem so that the IIC does not stop
> properly. I guess this could be the wrong timming parameters set.
> >
>
> This could be one of the "bugs" I found in the driver code. When you
> are master, and request a transmission from the slave which is < 2
> bytes (ie 1 byte), you should immediately set the TXAK of the ibcr to
> high (ie, no-ack signal), so that the slave knows to stop
> transmitting. Acording to the documentation and the sample code, this
> is only done when the 2nd to last bit is sent (which is never the
> case with <2 bits).
>
> I would have assumed that a STOP should sort this out, but it didn't
> seem to.
>

The master can only send a STOP (or a RESTART) condition when
it owns the data line. That is why you have to send the STOP
condition instead of the ACK after the last byte when receiving
from a slave because it is only here that the master for sure
can let data go high when clock is high.

If the master already have ACKed a byte and sets the clock low
for the next bit, the slave takes over the data line and if
next bit from the slave is 0, the slave holds the line low
during the entire time the clock line is high, preventing the
master from setting the data line high (through the pull upp
resistor).

Possibly the slave can sense a STOP condition when it is
sending a '1' bit in a byte, if it is even checking for a STOP
condition then (I don't know if it has to).

Ruben
==============================
Ruben Jsson
AB Liros Electronic
Box 9124, 200 39 Malm Sweden
TEL INT +46 40142078
FAX INT +46 40947388

==============================



> >
> >
> > > My driver has a marginal problem so that the IIC does not stop
> > properly. I guess this could be the wrong timming parameters set.
> > >
> >
> > This could be one of the "bugs" I found in the driver code. When you
> > are master, and request a transmission from the slave which is < 2
> > bytes (ie 1 byte), you should immediately set the TXAK of the ibcr to
> > high (ie, no-ack signal), so that the slave knows to stop
> > transmitting. Acording to the documentation and the sample code, this
> > is only done when the 2nd to last bit is sent (which is never the
> > case with <2 bits).
> >
> > I would have assumed that a STOP should sort this out, but it didn't
> > seem to.
> >
>
> The master can only send a STOP (or a RESTART) condition when
> it owns the data line. That is why you have to send the STOP
> condition instead of the ACK after the last byte when receiving
> from a slave because it is only here that the master for sure
> can let data go high when clock is high.

Correction: The stop condition should be sent after an not
acknoledge bit (SDA high) after the received byte according to
the I2C specs. When I have bit banged a master talking to an
EEPROM it has also worked to send the STOP condition instead of
the ACK cycle (since the master owns the DTA line here also).

>
> If the master already have ACKed a byte and sets the clock low
> for the next bit, the slave takes over the data line and if
> next bit from the slave is 0, the slave holds the line low
> during the entire time the clock line is high, preventing the
> master from setting the data line high (through the pull upp
> resistor).
>
> Possibly the slave can sense a STOP condition when it is
> sending a '1' bit in a byte, if it is even checking for a STOP
> condition then (I don't know if it has to).
>
> Ruben
> ==============================
> Ruben Jsson
> AB Liros Electronic
> Box 9124, 200 39 Malm Sweden
> TEL INT +46 40142078
> FAX INT +46 40947388
>
> ============================== >
> click here >
>
> Yahoo! Groups Links
> * To
>

==============================
Ruben Jsson
AB Liros Electronic
Box 9124, 200 39 Malm Sweden
TEL INT +46 40142078
FAX INT +46 40947388

==============================


Hi

RE:
>According to the documentation and the sample code, this
> is only done when the 2nd to last bit is sent (which is never the
> case with <2 bits).

I see that in my program I have changed the a line that decides if there will be acknowledgement and have a comment //second to last or last chr. rx. This is different too the original example, but then I cut the example down a lot.

>
> I would have assumed that a STOP should sort this out, but it didn't
> seem to.

The other point I made is that my driver is marginal some times working and sometimes one of the lines becomes stuck low. It's a few months since I last looked at the code, but I think I tried disabling the IIC after completing a cycle of Tx/Rx successfully cleared the bit sticking, but that was wrong and I have not left it that way.

Ruben's point about terminating with a stop instead of ack could also be relevant, but I still think that in my case the clock dividers setting is the primary issue. I use 16MHz bus and have one 400KHz IIC device, the setting I use is from the application note AN2318/D is:-

//IBFD = $80 SDA hold time = 28 clock cycles = 3.5uS @ 8MHz (NOT VALID)

It could be that Ruben has identified Steve's primary problem. I have pasted my IIC interrupt handler below, the headers are from AN2485, which incidentally seem virtually mistake free.
Andrew Lohmann AIIE
Design Engineer

PLEASE NOTE NEW EMAIL ADDRESS IS: Bellingham + Stanley Ltd.
Longfield Road, Tunbridge Wells, Kent, TN2 3EY, England.
Tel: +44 (0) 1892 500400
Fax: +44 (0) 1892 543115
Website: www.bs-ltd.com

@far void IIC_handler ()
{
UCHAR Dummy;

Iic.ibsr.bit.ibif = 1; // This also clears IAAS flag

// TCF is not reliable says Mot. app. note therefore don't use it. try again 30-04-04
if (Iic.ibsr.bit.tcf) // transfer complete (RX or TX) ** redundantish
{
if (Iic.ibcr.bit.txrx) // Transmitting
{
if (Iic.ibsr.bit.rxak) // Receive Acknowledge
{
Status |= StatErrorIsrAck;
Iic.ibcr.bit.mssl = 0; // stop condition.
}
else // acknowledged
if (Tx_ptr < Tx_nb) // send another char
Iic.ibdr.byte = Tx_buf[Tx_ptr++];
else
if (Rx_ptr >= Rx_top) // additional to app. note AL 29-04-04
Iic.ibcr.bit.mssl = 0; // stop condition
else
if (Tx_ptr == Tx_nb)
{
Iic.ibcr.bit.rsta = 1; // second start
Iic.ibdr.byte = (UCHAR)(Tx_buf[0] | iic_wr); // now write
Tx_ptr++;
}
else
{
Iic.ibcr.bit.txrx = 0; // switch to read mode.
Dummy = Iic.ibdr.byte; // dummy read
}
}
else
{ // receive char
if ((Rx_ptr + 1) >= Rx_top)
Iic.ibcr.bit.mssl = 0; // stop condition.

if ((Rx_ptr + 2) >= Rx_top) // second to last or last chr. rx.
Iic.ibcr.bit.txak = 1; // don't acknowledge.

*(Rx_ptr++) = Iic.ibdr.byte;
}
}
else
Status |= StatErrorIsr;
}


In a recent thread I think the originator asked about how do you prevent receive acknowledgement if you are only going to receive one byte. Therefore the test in the Block guide V02.07 fig 5-1 for second to last byte read can never be true. The ISR I copied in a previous email works 2 >= or 2 == makes no difference.

To resolve the problem: if prior to enabling the IIC block I test to see how many characters I expect to be returned == 1 then I set TXAK prior to turning on IIC and the ISR.

My FM24C64 can run a bit faster at 1MHz than standard 100KHz or 400KHz, and the baudrate factor of 0 theoretically only allows it to run at 67% of capability. It now works fine. It a shame you need simultaneous equations to work it out or else write down what you need then look down the table provided. Andrew Lohmann AIIE
Design Engineer

PLEASE NOTE NEW EMAIL ADDRESS IS: Bellingham + Stanley Ltd.
Longfield Road, Tunbridge Wells, Kent, TN2 3EY, England.
Tel: +44 (0) 1892 500400
Fax: +44 (0) 1892 543115
Website: www.bs-ltd.com



The 2024 Embedded Online Conference