EmbeddedRelated.com
Forums

IIC bus locks

Started by Jordi Costa October 28, 2004
Hi all,

I have HCS12 communicating with just an IIC slave device (M41T56, DS1307). If for some reason (program restart, parasitic noise on bus, .......) communication is stoped while slave is sending a 0, SDA line is held down and the master cannot control the bus again and an arbitration error is returned.

Peripheral does not have any way to force a hardware reset.

Any way to deal with the arbitration error from the master side ?

Regards,

Jordi Costa



Hello, Jordi

I've some problems with IIC bus.
I can't use IIC functionnality of the processor (HCS12dp256), because it
locks.
I didn't understand IIC system on this processor...
So I developed my own driver IIC, entirely in soft, which don't use
interrupt...
I uploaded it in the files area.
But you, may be you can tell me how you use IIC fonctionnality ?
Thanks.

Best regards.

Joel
-----Message d'origine-----
De : Jordi Costa [mailto:]
Envoy: jeudi 28 octobre 2004 10:39
:
Objet : [68HC12] IIC bus locks Hi all,

I have HCS12 communicating with just an IIC slave device (M41T56, DS1307).
If for some reason (program restart, parasitic noise on bus, .......)
communication is stoped while slave is sending a 0, SDA line is held down
and the master cannot control the bus again and an arbitration error is
returned.

Peripheral does not have any way to force a hardware reset.

Any way to deal with the arbitration error from the master side ?

Regards,

Jordi Costa
------------------------ Yahoo! Groups Sponsor --------------------~-->
$9.95 domain names from Yahoo!. Register anything.
http://us.click.yahoo.com/J8kdrA/y20IAA/yQLSAA/dN_tlB/TM
--------------------------------~- Yahoo! Groups Links


Joel,

I'm using internal HCS12 IIC peripheral, but without interrupts. I had the
system working some time, but now, due another software bug I discovered the
explained case.

I had a look to list archives and I found a not answered message regarding
HCS12 IIC single master locking while bus lines are both high.

I just downloaded your code and I'm going to have a look.

Thank you,

Jordi ----- Original Message -----
From: <>
To: <>
Sent: Thursday, October 28, 2004 7:14 PM
Subject: RE: [68HC12] IIC bus locks
Hello, Jordi

I've some problems with IIC bus.
I can't use IIC functionnality of the processor (HCS12dp256), because it
locks.
I didn't understand IIC system on this processor...
So I developed my own driver IIC, entirely in soft, which don't use
interrupt...
I uploaded it in the files area.
But you, may be you can tell me how you use IIC fonctionnality ?
Thanks.

Best regards.

Joel
-----Message d'origine-----
De : Jordi Costa [mailto:]
Envoy: jeudi 28 octobre 2004 10:39
:
Objet : [68HC12] IIC bus locks Hi all,

I have HCS12 communicating with just an IIC slave device (M41T56, DS1307).
If for some reason (program restart, parasitic noise on bus, .......)
communication is stoped while slave is sending a 0, SDA line is held down
and the master cannot control the bus again and an arbitration error is
returned.

Peripheral does not have any way to force a hardware reset.

Any way to deal with the arbitration error from the master side ?

Regards,

Jordi Costa


Jordi Costa wrote:

> Hi all,
>
> I have HCS12 communicating with just an IIC slave device (M41T56,
> DS1307). If for some reason (program restart, parasitic noise on bus,
> .......) communication is stoped while slave is sending a 0, SDA line
> is held down and the master cannot control the bus again and an
> arbitration error is returned.
>
> Peripheral does not have any way to force a hardware reset.

I think I managed to get around this problem, which occurred when
receiving one byte only, by disabling the IIC master and manually
driving the SCL pin to create another clock the ICC port can then be
enabled. Remember that high is open collector. It turned out that that
was not the real problem causing the locking of the SDA line low. I
added the code below early but just after enabling the IIC bus to my
read function that sets up the ISR to test for the case of only reading
one byte:-

Iic.ibcr.byte = IBEN | IBIE | TXRX | MSSL; // Enable & Start Tx Iic
module AL 11-05-04

if (nb_rec == 1) // cant' do second to last in ISR AL 11-08-04
Iic.ibcr.bit.txak = 1; // don't acknowledge.

The ISR is similar or the same as the one I posted in about July:-

@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. - AL
10-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 ** 0 ==
removed AL 28-04-04
{
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) // note == also works. was
tried AL 10-08-04
Iic.ibcr.bit.mssl = 0; // stop condition.

if ((Rx_ptr + 2) >= Rx_top) // second to last or last
chr. rx. - == works as well tried AL 10-08-04
Iic.ibcr.bit.txak = 1; // don't acknowledge.

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

--
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


Andrew,

Thanks for your info. My code seems to work under normal conditions, even in
one byte case, and "unrecoverable locking" was caused by a bug that stopped
the communication.

Maybe it is not necessary, but I will try to force the situation next week
and experiment by driving SCL as you suggest. I thought something similar
could be done from inside the IIC peripheral.

I'll keep you informed,

Jordi

----- Original Message -----
From: "Andrew Lohmann" <>
To: <>
Sent: Friday, October 29, 2004 10:00 AM
Subject: Re: [68HC12] IIC bus locks >
> Jordi Costa wrote:
>
> > Hi all,
> >
> > I have HCS12 communicating with just an IIC slave device (M41T56,
> > DS1307). If for some reason (program restart, parasitic noise on bus,
> > .......) communication is stoped while slave is sending a 0, SDA line
> > is held down and the master cannot control the bus again and an
> > arbitration error is returned.
> >
> > Peripheral does not have any way to force a hardware reset.
>
> I think I managed to get around this problem, which occurred when
> receiving one byte only, by disabling the IIC master and manually
> driving the SCL pin to create another clock the ICC port can then be
> enabled. Remember that high is open collector. It turned out that that
> was not the real problem causing the locking of the SDA line low. I
> added the code below early but just after enabling the IIC bus to my
> read function that sets up the ISR to test for the case of only reading
> one byte:-
>
> Iic.ibcr.byte = IBEN | IBIE | TXRX | MSSL; // Enable & Start Tx Iic
> module AL 11-05-04
>
> if (nb_rec == 1) // cant' do second to last in ISR AL 11-08-04
> Iic.ibcr.bit.txak = 1; // don't acknowledge.
>
> The ISR is similar or the same as the one I posted in about July:-
>
> @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. - AL
> 10-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 ** 0 ==
> removed AL 28-04-04
> {
> 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) // note == also works. was
> tried AL 10-08-04
> Iic.ibcr.bit.mssl = 0; // stop condition.
>
> if ((Rx_ptr + 2) >= Rx_top) // second to last or last
> chr. rx. - == works as well tried AL 10-08-04
> Iic.ibcr.bit.txak = 1; // don't acknowledge.
>
> *(Rx_ptr++) = Iic.ibdr.byte;
> }
> }
> else
> Status |= StatErrorIsr;
> }
>
> --
> 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 >
> Yahoo! Groups Links >
>





Hello,

On October 2004 Jordi Costa posted the following:

"I have HCS12 communicating with just an IIC slave device (M41T56,
DS1307). If for some reason (program restart, parasitic noise on bus,
.......) communication is stopped while slave is sending a 0, SDA line
is held down and the master cannot control the bus again and an
arbitration error is returned."

I don't know if he managed to find a solution, and I've got the same
problem with an HCS12. The IIC spec says that the procedure to
software reset the bus is the following:

1. send 9 clock pulses on SCL with SDA high
2. send a STOP

The idea is that sometime during the 9 pulses the slave-transmitter
will release SDA and expect an ACK. It will get a NACK from the master
(the HCS12), since we let SDA=1. The slave will then release the bus.

This works fine if I disable the IIC module and bit bang on
PORTJ[6:7], but I was also looking for a better solution involving the
IIC module.

The MCF5307 Coldfire also has an IIC module, and it is essentially
identical the the HCS12's. Its manual states the following on page
8-10:

"If IBSR[IBB] when the I2C bus module is enabled, execute the
following code sequence before proceeding with normal initialization
code. This issues a STOP command to the slave device, placing it in
idle state as if it were just power-cycled on."

I2CR = 0x0
I2CR = 0xA
dummy read of I2DR
IBSR = 0x0
I2CR = 0x0

Unfortunately this is rubbish. The commands don't even make any sense,
since I2CR = 0xA writes to a reserved bit.

Does anyknow know how to software reset the IIC bus using the IIC
module? I'm trying to get an answer out of Freescale's support, but
the person answering my service requests doesn't seem to understand
what I really want.

Thanks for your attention.

Best regards,

Flavio



Flavio,

I never fixed the problem but situation seems not to arise under normal use
and proper circuit board. Problem was really detected when prototyping with
some wiring attached on board.

Anyway I'm still interested in a good fix to prevent it. My intention was to
force the state and try some bit banging as yours to release the bus, but
other tasks kept me away from this matter.

Please keep us informed of any progress.

Jordi Costa ----- Original Message -----
From: "Flavio Protasio Ribeiro" <>
To: <>
Sent: Monday, February 07, 2005 5:52 PM
Subject: [68HC12] IIC bus locks >
>
> Hello,
>
> On October 2004 Jordi Costa posted the following:
>
> "I have HCS12 communicating with just an IIC slave device (M41T56,
> DS1307). If for some reason (program restart, parasitic noise on bus,
> .......) communication is stopped while slave is sending a 0, SDA line
> is held down and the master cannot control the bus again and an
> arbitration error is returned."
>
> I don't know if he managed to find a solution, and I've got the same
> problem with an HCS12. The IIC spec says that the procedure to
> software reset the bus is the following:
>
> 1. send 9 clock pulses on SCL with SDA high
> 2. send a STOP
>
> The idea is that sometime during the 9 pulses the slave-transmitter
> will release SDA and expect an ACK. It will get a NACK from the master
> (the HCS12), since we let SDA=1. The slave will then release the bus.
>
> This works fine if I disable the IIC module and bit bang on
> PORTJ[6:7], but I was also looking for a better solution involving the
> IIC module.
>
> The MCF5307 Coldfire also has an IIC module, and it is essentially
> identical the the HCS12's. Its manual states the following on page
> 8-10:
>
> "If IBSR[IBB] when the I2C bus module is enabled, execute the
> following code sequence before proceeding with normal initialization
> code. This issues a STOP command to the slave device, placing it in
> idle state as if it were just power-cycled on."
>
> I2CR = 0x0
> I2CR = 0xA
> dummy read of I2DR
> IBSR = 0x0
> I2CR = 0x0
>
> Unfortunately this is rubbish. The commands don't even make any sense,
> since I2CR = 0xA writes to a reserved bit.
>
> Does anyknow know how to software reset the IIC bus using the IIC
> module? I'm trying to get an answer out of Freescale's support, but
> the person answering my service requests doesn't seem to understand
> what I really want.
>
> Thanks for your attention.
>
> Best regards,
>
> Flavio
>




Jordi,

I also don't get this problem under normal use, but it could manifest
itself if the HCS12 is powered down while communicating with a
battery-powered IIC device such as a clock/calendar.

I'll keep you posted.

Best regards,

Flavio

--- In , "Jordi Costa" <bvjordi@b...> wrote:
> Flavio,
>
> I never fixed the problem but situation seems not to arise under
> normal use and proper circuit board. Problem was really detected
> when prototyping with some wiring attached on board.
>
> Anyway I'm still interested in a good fix to prevent it. My
> intention was to force the state and try some bit banging as
> yours to release the bus, but other tasks kept me away from
> this matter.
>
> Please keep us informed of any progress.
>
> Jordi Costa > ----- Original Message -----
> From: "Flavio Protasio Ribeiro" <flavio@h...>
> To: <>
> Sent: Monday, February 07, 2005 5:52 PM
> Subject: [68HC12] IIC bus locks > >
> >
> > Hello,
> >
> > On October 2004 Jordi Costa posted the following:
> >
> > "I have HCS12 communicating with just an IIC slave device (M41T56,
> > DS1307). If for some reason (program restart, parasitic noise on
bus,
> > .......) communication is stopped while slave is sending a 0, SDA
line
> > is held down and the master cannot control the bus again and an
> > arbitration error is returned."
> >
> > I don't know if he managed to find a solution, and I've got the
same
> > problem with an HCS12. The IIC spec says that the procedure to
> > software reset the bus is the following:
> >
> > 1. send 9 clock pulses on SCL with SDA high
> > 2. send a STOP
> >
> > The idea is that sometime during the 9 pulses the
slave-transmitter
> > will release SDA and expect an ACK. It will get a NACK from the
master
> > (the HCS12), since we let SDA=1. The slave will then release the
bus.
> >
> > This works fine if I disable the IIC module and bit bang on
> > PORTJ[6:7], but I was also looking for a better solution
involving the
> > IIC module.
> >
> > The MCF5307 Coldfire also has an IIC module, and it is essentially
> > identical the the HCS12's. Its manual states the following on page
> > 8-10:
> >
> > "If IBSR[IBB] when the I2C bus module is enabled, execute the
> > following code sequence before proceeding with normal
initialization
> > code. This issues a STOP command to the slave device, placing it
in
> > idle state as if it were just power-cycled on."
> >
> > I2CR = 0x0
> > I2CR = 0xA
> > dummy read of I2DR
> > IBSR = 0x0
> > I2CR = 0x0
> >
> > Unfortunately this is rubbish. The commands don't even make any
sense,
> > since I2CR = 0xA writes to a reserved bit.
> >
> > Does anyknow know how to software reset the IIC bus using the IIC
> > module? I'm trying to get an answer out of Freescale's support,
but
> > the person answering my service requests doesn't seem to
understand
> > what I really want.
> >
> > Thanks for your attention.
> >
> > Best regards,
> >
> > Flavio
> >



At 2005-02-07 18:47, Flavio Protasio Ribeiro wrote:
>I also don't get this problem under normal use, but it could manifest
>itself if the HCS12 is powered down while communicating with a
>battery-powered IIC device such as a clock/calendar.

Perhaps the HC12 can't pull down the lines low enough
when it's powered down?

You don't need fancy equipment to test this: Just write
a software version that pulls down the lines forever
in powered down mode and use a volt meter.

Alternatively you could also experiment with other
external pull-up resistor values.

Do you use an external resistor or do you use the one
in the output port of the HC12? If so, perhaps that
isn't powerful enough in powered down mode?

Greetings,
Jaap



By "powered down" I meant "turned off", so I'm pretty sure it won't
pull the lines low enough :)

Best regards,

Flavio

--- In , Jaap van Ganswijk <ganswijk@x> wrote:
> At 2005-02-07 18:47, Flavio Protasio Ribeiro wrote:
> >I also don't get this problem under normal use, but it could
manifest
> >itself if the HCS12 is powered down while communicating with a
> >battery-powered IIC device such as a clock/calendar.
>
> Perhaps the HC12 can't pull down the lines low enough
> when it's powered down?
>
> You don't need fancy equipment to test this: Just write
> a software version that pulls down the lines forever
> in powered down mode and use a volt meter.
>
> Alternatively you could also experiment with other
> external pull-up resistor values.
>
> Do you use an external resistor or do you use the one
> in the output port of the HC12? If so, perhaps that
> isn't powerful enough in powered down mode?
>
> Greetings,
> Jaap