Dear support,
I would really need support with the I2C-bus.
Have a system with XMC4500 up and running, it can operate for several weeks until suddenly the I2C-bus stops responding.
The XMC4500 is master, and have two slave pheriperals: a IO-expander and a RTC.
It uses I2C001-app 1.0.28 with FIFO buffers for both RX and TX.
I queue up all TDF-codes and data to the FIFO. The interrupt handler counts ack-interrupts and sets a semaphore when the stop condition is transfeered. I can therefore verify a successful write without doing "busy wait".
It works great until a fault conditon occurs. I have in the past already implemented a fail recovery mechanism which is called once before i issue a new I2C start condition:
if(I2C001_Handle0.I2CRegs->TCSR & USIC_CH_TCSR_TDV_Msk){
//Recover from an error state
I2C001_Handle0.I2CRegs->PSCR |= 0x3FF;
// Flush FIFO buffer
USIC_FlushTxFIFO(I2C001_Handle0.I2CRegs);
USIC_FlushRxFIFO(I2C001_Handle0.I2CRegs);
// Modify Transmit Data Valid
I2C001_Handle0.I2CRegs->FMR |= (((uint32_t) 2) << USIC_CH_FMR_MTDV_Pos) & USIC_CH_FMR_MTDV_Msk;
}
This has proven to not be sufficient - the I2C-bus still stays in a non responding state.
Have read the reference manual, and I belive that it must be due to out of synch with one of the pheriperals. Maybe the bus has switched direction, and the
bus is not idle once i issue a new start condition. It can also be out of synch with the state machine of the pheriperal - the TDF-code is not accepted at the current state.
But how do i recover from this state? By the reference manual it seems like i need to act different depending on current state. But this is quite complicated when using a FIFO - What command did it go wrong? How to react? ...
Isn't there a fool-prof way of resetting the bus forceing it back to idle?
I would really need support with the I2C-bus.
Have a system with XMC4500 up and running, it can operate for several weeks until suddenly the I2C-bus stops responding.
The XMC4500 is master, and have two slave pheriperals: a IO-expander and a RTC.
It uses I2C001-app 1.0.28 with FIFO buffers for both RX and TX.
I queue up all TDF-codes and data to the FIFO. The interrupt handler counts ack-interrupts and sets a semaphore when the stop condition is transfeered. I can therefore verify a successful write without doing "busy wait".
It works great until a fault conditon occurs. I have in the past already implemented a fail recovery mechanism which is called once before i issue a new I2C start condition:
if(I2C001_Handle0.I2CRegs->TCSR & USIC_CH_TCSR_TDV_Msk){
//Recover from an error state
I2C001_Handle0.I2CRegs->PSCR |= 0x3FF;
// Flush FIFO buffer
USIC_FlushTxFIFO(I2C001_Handle0.I2CRegs);
USIC_FlushRxFIFO(I2C001_Handle0.I2CRegs);
// Modify Transmit Data Valid
I2C001_Handle0.I2CRegs->FMR |= (((uint32_t) 2) << USIC_CH_FMR_MTDV_Pos) & USIC_CH_FMR_MTDV_Msk;
}
This has proven to not be sufficient - the I2C-bus still stays in a non responding state.
Have read the reference manual, and I belive that it must be due to out of synch with one of the pheriperals. Maybe the bus has switched direction, and the
bus is not idle once i issue a new start condition. It can also be out of synch with the state machine of the pheriperal - the TDF-code is not accepted at the current state.
But how do i recover from this state? By the reference manual it seems like i need to act different depending on current state. But this is quite complicated when using a FIFO - What command did it go wrong? How to react? ...
Isn't there a fool-prof way of resetting the bus forceing it back to idle?