Reply by Martijn Broens April 10, 20092009-04-10
Hi 42Bastion,

Okay makes sense can that be done as i described in my prev post??

thanks martijn

_____

From: l... [mailto:l...] On Behalf Of
42Bastian
Sent: vrijdag 10 april 2009 12:45
To: l...
Subject: Re: [lpc2000] Re: I2C reset??

Hi Martijn
> And if I than halt the attach the debugger and
> halt the processor I can see that its in a while(1) loop trying to send a
> stop condition See below.

You should always have some sort of time out on reading HW status and
abort the action.

That is, if your STOP times out, you have to restart the RESET procedure.

--
42Bastian

Note: SPAM-only account, direct mail to bs42@...



An Engineer's Guide to the LPC2100 Series

Reply by 42Bastian April 10, 20092009-04-10
Hi Martijn
> And if I than halt the attach the debugger and
> halt the processor I can see that its in a while(1) loop trying to send a
> stop condition See below.

You should always have some sort of time out on reading HW status and
abort the action.

That is, if your STOP times out, you have to restart the RESET procedure.
--
42Bastian

Note: SPAM-only account, direct mail to bs42@...
Reply by Martijn Broens April 10, 20092009-04-10
Hi Walter,

My intention.. well. I've ben using the I2C bus for a while now in my
project. And we are close to a release. I have a my I2C bus from the LPC2468
connected to a PCA9507 I2C Bus extender. That's on my main board, The
peripherals are connected with a connector to the main board. And so far we
use 4 IO extender (PCA9532) for buttons and GPIO. These all worked well. But
occasionally my I2C hangs. And if I than halt the attach the debugger and
halt the processor I can see that its in a while(1) loop trying to send a
stop condition See below.

So far I have been unable to find a way to simulate this but as I mentioned
occasionally it happens. If I put my logic analyser on the bus I can see
that the SCL did not come high but the SDA changed from low-to-high. ??? as
a work around for now I was thinking okay. Try sending a stop for x times if
his did not succeed. Break and send a reset tell the higher level it went
wrong and done. Where back in bussines.

That's what my intention is

Perhaps there are other cenario's please feel free to share them.

BTW the clock is set to: cclk/8

S8 i2cStop(char port) {

int reties = 0;

switch (port){

case 0: // EEPROM_PORT

I2C0CONSET |= 0x14; /* STO=1 and AA = 1 */

I2C0CONCLR = 0x08; /* clear SI flag */

/* wait for STOP detected (while STO = 1) */

while((I2C0CONSET & 0x10) == I2CERR_REPEATEDSTARTTX ) {

/* do nothing */

;

}

break;

case 1: //

I2C1CONSET |= 0x14; /* STO=1 and AA = 1 */

I2C1CONCLR = 0x08; /* clear SI flag */

/* wait for STOP detected (while STO = 1) */

while((I2C1CONSET & 0x10) == I2CERR_REPEATEDSTARTTX ) {

/* do nothing */

;

}

break;

case 2: // PCA9532_PORT

I2C2CONSET |= 0x14; /* STO=1 and AA = 1 */

I2C2CONCLR = 0x08; /* clear SI flag */

reties = 0;

/* wait for STOP detected (while STO = 1) */

while((I2C2CONSET & 0x10) == I2CERR_REPEATEDSTARTTX ) { // 0x10

#ifdef I2C_RESET

if(reties++ > I2C_MAX_RETRIES){

i2cReset(port);

break;

}

#else

/* do nothing */

;
// this is where the code hangs!!!!!

#endif

}

break;

}

DEBUGP("i2cStop: %x\n", I2C_CODE_OK);

/*insert a small delay for bus free time*/

int delay = 1000; while(delay--) ;

return I2C_CODE_OK;

}

thanks martijn

_____

From: l... [mailto:l...] On Behalf Of
Walter
Sent: vrijdag 10 april 2009 11:49
To: l...
Subject: [lpc2000] Re: I2C reset??

--- In lpc2000@yahoogroups .com, "Martijn
Broens" wrote:
>
> reset, any 2-wire
>
> part can be protocol reset by following these steps: (a) Create a start
bit
> condition, (b)
>
> clock 9 cycles, (c) create another start bit followed by stop bit
condition
> as shown below.
>
> The device is ready for next communication after above steps have been
> completed."
>
Hi Martijn,

This is indeed similar to what I described, several I2C devices internally
start executing the previously received message on the STOP bit so in case
of unknown state it is considered wrong to send a STOP to avoid starting on
random data but a START condition doesn't hurt.

Still it is unclear what your intention is. All I2C slave devices I know do
not need any bus related initialisation. After the bus master is initialised
you can just begin initialising the slaves by writing the register values as
specified by the data sheets following the specified scenarios.

Only in case the bus gets locked (data or clock line is low when the master
wants to start communication) special actions are needed to solve this by
either sending repeated starts and clock pulses or even powering clients
off. But this is not an initialisation issue but can occur at any time if a
slave device gets into an undefined state.

Normally an I2C driver will do several checks at specific moments:

Before generating start condition:
Is data and clock line in high state?

During slave addressing stage:
Do the lines return to high level when master sets them high?

After slave address is transmitted:
Does the addressed slave acknowledge?

During sending next data:
Do the bus lines follow or does the slave try to slow down by so called
clock stretching?
Is every data byte acknowledged?

Etc.

And any error condition will need to be handled by retry, reset, power
cycling etc.

--
Kind regards,
Walter



Reply by Walter April 10, 20092009-04-10
--- In l..., "Martijn Broens" wrote:
>
> reset, any 2-wire
>
> part can be protocol reset by following these steps: (a) Create a start bit
> condition, (b)
>
> clock 9 cycles, (c) create another start bit followed by stop bit condition
> as shown below.
>
> The device is ready for next communication after above steps have been
> completed."
>
Hi Martijn,

This is indeed similar to what I described, several I2C devices internally start executing the previously received message on the STOP bit so in case of unknown state it is considered wrong to send a STOP to avoid starting on random data but a START condition doesn't hurt.

Still it is unclear what your intention is. All I2C slave devices I know do not need any bus related initialisation. After the bus master is initialised you can just begin initialising the slaves by writing the register values as specified by the data sheets following the specified scenarios.

Only in case the bus gets locked (data or clock line is low when the master wants to start communication) special actions are needed to solve this by either sending repeated starts and clock pulses or even powering clients off. But this is not an initialisation issue but can occur at any time if a slave device gets into an undefined state.

Normally an I2C driver will do several checks at specific moments:

Before generating start condition:
Is data and clock line in high state?

During slave addressing stage:
Do the lines return to high level when master sets them high?

After slave address is transmitted:
Does the addressed slave acknowledge?

During sending next data:
Do the bus lines follow or does the slave try to slow down by so called clock stretching?
Is every data byte acknowledged?

Etc.

And any error condition will need to be handled by retry, reset, power cycling etc.

--
Kind regards,
Walter

Reply by Martijn Broens April 10, 20092009-04-10
Hi Walter,

I found the following in a datasheet from Atmel (AT24C512B) page 6:

"Software Reset: After an interruption in protocol, power loss or system
reset, any 2-wire

part can be protocol reset by following these steps: (a) Create a start bit
condition, (b)

clock 9 cycles, (c) create another start bit followed by stop bit condition
as shown below.

The device is ready for next communication after above steps have been
completed."

I thought of doing it as follows: but I guess this is not complete, since in
my case the master (the LPC itself) got hung in the state machine.

So I guess I will also need to add the following:

/* clear flags */

I2C0CONCLR I2C0CONSET_I2EN|I2C0CONSET_STA|I2C0CONSET_SI|I2C0CONSET_AA;

/* reset registers */

I2C2SCLL = ( I2C2SCLL & ~I2C_REG_SCLL_MASK ) | I2C_REG_SCLL;
// set speed

I2C2SCLH = ( I2C2SCLH & ~I2C_REG_SCLH_MASK ) | I2C_REG_SCLH;
// set speed

I2C2ADR = ( I2C2ADR & ~I2C_REG_ADDR_MASK ) | I2C_REG_ADDR;
//

I2C2CONSET = ( I2C2CONSET & ~I2C_REG_CONSET_MASK ) | I2C_REG_CONSET;
//

For initialising the HW in the LPC.

/***************************************************************************
***

*

* Description:

* Software Reset:

After an interruption in protocol, power loss or system reset, any
2-wire

part can be protocol reset by following these steps:

(a) Create a start bit condition,

(b) clock 9 cycles,

(c) create another start bit followed by stop bit condition as shown
below.

The device is ready for next communication after above steps have been
completed.

___ ___ ___ ___ ___ ___ ___ ___

SCL ____| s |_| 1 |_| 2 |_| 3 |_ // _| 8 |_| 9 |_| s |_| h |_

_____ ______________________________________ ___

SDA |___| |____|

*

****************************************************************************
*/

void i2cReset(char port) {

i2cStart(port);

// set SDA high

// shift out 9 clocks.

i2cPutChar(port, 0xFF);

i2cStart(port);

i2cStop(port);

}

thanks martijn

_____

From: l... [mailto:l...] On Behalf Of
Walter
Sent: donderdag 9 april 2009 17:14
To: l...
Subject: [lpc2000] Re: I2C reset??

--- In lpc2000@yahoogroups .com, "Martijn
Broens" wrote:
> I'd like to implement a reset function for I2C but don;'t quite
>
What is your intention of the reset function? Do you want to reset the
peripherals connected to the bus or the controller itself?

For the peripherals I think it is best to send a series of repeated starts,
never send stop as it could trigger a write operation in an previously
erratically addressed peripheral.

So far from my knowledge of 10+ years of SW engineering in TV circuits.

--
Kind regards,
Walter



Reply by Walter April 9, 20092009-04-09
--- In l..., "Martijn Broens" wrote:
> I'd like to implement a reset function for I2C but don;'t quite
>
What is your intention of the reset function? Do you want to reset the peripherals connected to the bus or the controller itself?

For the peripherals I think it is best to send a series of repeated starts, never send stop as it could trigger a write operation in an previously erratically addressed peripheral.

So far from my knowledge of 10+ years of SW engineering in TV circuits.

--
Kind regards,
Walter

Reply by Martijn Broens April 9, 20092009-04-09
Hi everybody,

I'd like to implement a reset function for I2C but don;'t quite know how to.
Did anybody already do this?? And is willing to share the info/code??

I'm using the lpc2468 but Im guessing this is equal for all system as this
is most likle a protocol??

thanks martijn