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
I2C reset??
Started by ●April 9, 2009
Reply by ●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
> 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 ●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
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 ●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
>
> 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 ●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
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 ●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@...
> 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 ●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@...
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@...