XMC1100 I2C - Force release of SDA and SCL

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User8683
Level 4
Level 4
First like received
Hello,

I have been searching through the XMC1100 manual and register descriptions but cannot seem to find a way to forcibly release the SDA and SCL lines in the event of a communications error when the MCU is operating as an I2C slave. I have looked at the I2C PSR and the TRBSR and neither is complaining of any error. I think that the chip is simply trying to send out the remaining data but the master has stopped communications. I have tried writing out more bytes after the error, but the master is no longer listening or clocking. I have confirmed that it is the XMC1100 slave that is holding down either the SDA line preventing further bus activity. If I break the connection of the XMC1100 SDA to the bus, the master continues communications with other devices on the bus, having handled the error for itself.

The only part that I have found is for invalidating the buffer contents and clearing the buffer as follows:

/* Invalidate the transmission */
WR_REG( pI2CRegisters->FMR, USIC_CH_FMR_MTDV_Msk, USIC_CH_FMR_MTDV_Pos, 0x10 );

/* Flush the buffer */
SET_BIT( pI2CRegisters->TRBSCR, USIC_CH_TRBSCR_FLUSHTB_Pos );

So far only a chip reset frees the SDA lines to allow further communications.

Any ideas how to handle this or which documentation explains this scenario?

Thanks,

Jason
0 Likes
20 Replies
Not applicable
Hi,

Have you tried disabling the channel altogether by writing 0 to the MODE field in CCR register?
When the channel is disabled, all protocol related state machines should be reverted to an idle state.

Regards,
T.O.M.
0 Likes
User8683
Level 4
Level 4
First like received
Thanks for the response.

That was the obvious choice for me too, but toggling the MODE off and on does not return the system to the working state. If the SCL is held down by the XMC1000 at the time this is done, it remains down, although the SDA does return to high again. It seems only a partial solution and I am seeing that if I am going to go this route, a specific sequence will be needed, but it has so far been a lot of guess work without any success.

Thanks,

Jason
0 Likes
Not applicable
Hello again,

When the slave has no valid data to be transmitted in response to a master read request, it will hold SCL low. Could this be happening in the error scenario? If so, the solution is simply to write the transmit data to TBUF or FIFO if FIFO is used.

Otherwise, you can further try to toggle the clock gating to USIC in the SCU through CLKCR register (bit protected register) but I am not sure if this will deassert the SCL. I assume the error recovery steps to Flush the FIFO, clear TDV are still needed.
Example sequence:
	SCU_GENERAL->PASSWD = 0x000000C0UL;
SCU_CLK->CGATSET0 |= 0x00000008; // enable USIC clock gating
while((SCU_CLK->CLKCR)&0x40000000UL); // wait for VDDC to stabilize
SCU_GENERAL->PASSWD = 0x000000C3UL;

SCU_GENERAL->PASSWD = 0x000000C0UL;
SCU_CLK->CGATCLR0 |= 0x00000008; // stop gating USIC
while((SCU_CLK->CLKCR)&0x40000000UL); // wait for VDDC to stabilize
SCU_GENERAL->PASSWD = 0x000000C3UL;
0 Likes
User8683
Level 4
Level 4
First like received
Thanks for the suggestion. I have played with this a lot and it seems that when the error happens, the master decides communication is done and moves on. Thus, it doesn't send anymore clock pulses to shift the data out. All that happens is that I accumulate bytes in the FIFO buffer.

I will try your second approach, but I really wish the Infineon folks would give an answer and avoid the need for guessing. To me the documentation just seems incomplete and this would seem like a common scenario to handle for I2C communications.

Regards,

Jason
0 Likes
Not applicable
Hi Jason,

Could you provide the details how the error occurs?
Does the Master send the Stop condition to the Slave when error occurs?
From what I understand, the Slave only hold the line if the slave require the Master to wait.
If the Master send a stop condition to the slave, the slave shouldn't hold to the line.
0 Likes
User8683
Level 4
Level 4
First like received
The SCL not being released is occurring after a lot of message exchange so I am not sure of the exact scenario that normally causes it. It was observed after more 18 hours of ongoing messaging the first time and more than 10 hours the second time. Prior to the failure, all message exchanges are successful so it is infrequent and likely due to spurious noise rather than programmatic failure. That said, in trying to handle it, I have been creating 3 scenarios that look similar by doing a reset on the master which leaves the slave with SDA low, SCL low or both. In these created situations, it makes sense that the stop condition is not being received and that this is what leaves the XMC I2C state machine in this currently unrecoverable state. Unfortunately, because the XMC is holding the SCL down, the master cannot take any steps to recover the bus and continue.

Regardless of the cause, however, a device should never be completely dependent on changes in the attached bus in order to recover its state machine. It should always be able to reset to a working state even if the bus is behaving badly and will mess up the state machine immediately.

Now, to answer the second question that was asked of me in direct email:

"For topic 1, as long as the FIFO is stop, the flushing should be possible.
So we are wondering if the slave did not received the Stop condition from Master, hence, the slave is still trying to send out data which makes the flushing impossible.
It seems to us that topic 1 and topic 3 should be related. "

I have to ask what constitutes the FIFO being stopped? What we are doing in this scenario is detecting a bad response message from the I2C slave, sending a subsequent reset command to it and then attempting to reestablish communications. In trying to handle this, wait states have been introduced to possibly allow buffer clearing to occur but it does not happen. What does happen is something like the following:

0C is sent to XMC1100
A1 B2 C3 D4 E5 F6 07 should be returned

Instead, after lots of traffic, a byte is slipped or added for some reason so when:

0C is sent to XMC1100
07 A1 B2 C3 D4 E5 F6 is returned

Subsequently,

7A is sent to XMC1100 to try to reset communications

Then,

0C is sent to XMC1100
07 A1 B2 C3 D4 E5 F6 is again returned

In other words, after the initial very rare (once in hours of messaging) byte slip or duplicate byte, any attempt to reframe the bytes by clearing the FIFO is not successful. Again, it should be possible to reset the FIFO regardless of what has happened in the bus.
0 Likes
Not applicable
Hi Jason,

For the FIFO flushing, found this code on one of the post in the forum and it works for them.
Can you give it a try?
if(USIC1_CH1->PSR_IICMode & (USIC_CH_PSR_IICMode_ERR_Msk | USIC_CH_PSR_IICMode_NACK_Msk)) {
// Clear error bits
USIC1_CH1->PSCR |= 0x3FF;
// Flush transmit FIFO buffer
USIC1_CH1->TRBSCR |= USIC_CH_TRBSCR_FLUSHTB_Msk;
// Modify Transmit Data Valid
WR_REG(USIC1_CH1->FMR, USIC_CH_FMR_MTDV_Msk, USIC_CH_FMR_MTDV_Pos, 2);




As for the other question on resetting the IIC state machine, we are looking into it now.
0 Likes
User8683
Level 4
Level 4
First like received
Jackson,

Thanks for the suggestion.

I tried the commands listed and they do reduce the probability of the problem occurring but it still does occur on occasion so there may be multiple problems or possible ways of encountering the scenario. I still think that if any specific delays are required before messaging can be restarted following resets, that that would be good to know. That said, with the reduction in probability of the buffer clearing problem, the SDA and SCL being in a wrong state tends to happen more often than the buffer problem making it more challenging to reproduce the buffer problem.

Regards,

Jason
0 Likes
Not applicable
Hi Jason,

Do you mean that even after you use the code provided above to reset the FIFO, you still received the byte slip on the subsequence frame?
0 Likes
User8683
Level 4
Level 4
First like received
Jackson,

After resetting, I still get a byte coming out that is associated with the previous response. This byte should have been cleared when the FIFO was reset.

Jason
0 Likes
Not applicable
Hi Jason,

When we set FMR.MTDV = 2, the USIC should invalidate the data in the TBUF.
I couldn't think of other but the problem could be from the source.
So, I'm thinking that the data that loaded into the FIFO could already be corrupted before loading into the FIFO.
Do you mind to the load the same data to a RAM location and check if the data is correct after the USIC has reset its FIFO?
0 Likes
User8683
Level 4
Level 4
First like received
Jackson,

I have stepped through the writing of the individual I2C byte responses and the code is only writing out what it should. I can see that by the digital scope output. The problem is that as soon as the master makes a read request, the last byte from the previous request is sent back by the slave immediately because it is still in the FIFO buffer. Then, I get into the interrupt code and can see the writing of the desired bytes in order as expected. If I change the code to write 1 fewer byte to the FIFO in response to the master, then the master gets an error, but subsequent communications are restored. Unfortunately, performing this manual correction is guesswork.

As mentioned before, I believe that the buffer reset may take a certain number of clock cycles to clear. When I add these clock cycles, I do not get the same problem. Unfortunately, testing is troublesome because the SCL, SDA or both get into a wrong state and I have to reset the XMC1100 to continue.

Jason
0 Likes
Not applicable
Hi Jason,

We didn't really expect some delay is needed after clearing TDV bit.
Can I confirm the sequence with you again so we could further understand and provide this feedback to the related personal.

Is this your sequence how to reset the FIFO:
1) Flash the FIFO and clear TDV (as per provided code)
2) Add in delay of few clock cycles
3) Add new data into FIFO
0 Likes
User8683
Level 4
Level 4
First like received
The sequence I am using to reset the FIFO is as you stated. However, as mentioned previously, the SCL, SDA or both get into a wrong state frequently when I do this so I cannot easily reproduce it to say definitively that it is working. As to your comment about not expecting this to be required, can you explain what exactly the guide is referring to when it indicates that traffic should be stopped (p 492 "Should only be used while the FIFO buffer is not taking part in data traffic.") ?

Also, could the TBUS bit field be something that needs to be taken into account in terms of checking the state of this flag before flushing?

Finally, could the TBFLVL be checked in some way to see what is happening?
0 Likes
User8683
Level 4
Level 4
First like received
I would also like to know in what sort of time frame to expect more information about how to release the SCL and SDA lines as this is the bigger problem.
0 Likes
Not applicable
longtimer wrote:
The sequence I am using to reset the FIFO is as you stated. However, as mentioned previously, the SCL, SDA or both get into a wrong state frequently when I do this so I cannot easily reproduce it to say definitively that it is working. As to your comment about not expecting this to be required, can you explain what exactly the guide is referring to when it indicates that traffic should be stopped (p 492 "Should only be used while the FIFO buffer is not taking part in data traffic.") ?

Also, could the TBUS bit field be something that needs to be taken into account in terms of checking the state of this flag before flushing?

Finally, could the TBFLVL be checked in some way to see what is happening?


Hi Jason,

The traffic should be stop refers to no communication is on going for the particular USIC channel.
In any case, the communication must be is stopped and no data transfer is on going.
However, in your case, I believe the data transfer has been stopped due to the error and since there are no clock from master anymore.
What we suspected is the data in the shift register that are not cleared and sent out when you transmit the next data.
When we invalidated the data in shift register with FMR.MTDV = 2, the data should be cleared in the next clock cycle.
But it seems is not true in your case.
We will further investigate this issue.

longtimer wrote:
I would also like to know in what sort of time frame to expect more information about how to release the SCL and SDA lines as this is the bigger problem.


For resetting the I2C Slave to release the line, below is the suggestion from our expert:
- Switch data/clock alternate output pin function to GPIO input in order to release clock/data line from I2C slave side
- Flush Tx/RxFIFO via TRBSCR and release TBUF via FMR
- Clear all status bits e.g. PSR.. and re-initialize I2C USIC channel again if necessary
- Set alternate output pin for data/clock line

It is working as per our testing. Can you give it a try?
0 Likes
User8683
Level 4
Level 4
First like received
Thanks Jackson,

I finally have success and can recover from the problem after every time. Thanks for the details and the ordering of operations. One note that I would add for anyone else needing to do this is that a watchdog-type timer may be needed to invoke the reset the communications as per above as doing it in the actual communications interrupt handler can create other problems with SCL and SDA due to activity of the master.

As for the FIFO buffer problem, I am no longer able to reproduce it now that I am doing the buffer reset as a part of the overall I2C reset so I think that can also be closed off.

Thanks again,

Jason
0 Likes
Not applicable
Hi Jason,

Glad to hear that now the problem is solved.
We will review our USIC implementation to further improved it in our next design.
Thank you for your feedback too.
0 Likes
Not applicable
Hi Jackson,
I am coming to this situation as well. My I2C lines (and ohter lines as welll) pick up the noise and stop work. I am using XMC4500. (1) Could you please post the sample code, ideally also for xmc4500. (2) How can I disconnect the clock for U2C1 and reconnect the clock for U2C1?
thanks.



Jackson wrote:
Hi Jason,

The traffic should be stop refers to no communication is on going for the particular USIC channel.
In any case, the communication must be is stopped and no data transfer is on going.
However, in your case, I believe the data transfer has been stopped due to the error and since there are no clock from master anymore.
What we suspected is the data in the shift register that are not cleared and sent out when you transmit the next data.
When we invalidated the data in shift register with FMR.MTDV = 2, the data should be cleared in the next clock cycle.
But it seems is not true in your case.
We will further investigate this issue.



For resetting the I2C Slave to release the line, below is the suggestion from our expert:
- Switch data/clock alternate output pin function to GPIO input in order to release clock/data line from I2C slave side
- Flush Tx/RxFIFO via TRBSCR and release TBUF via FMR
- Clear all status bits e.g. PSR.. and re-initialize I2C USIC channel again if necessary
- Set alternate output pin for data/clock line

It is working as per our testing. Can you give it a try?
0 Likes
Not applicable
Hi shenj,

For XMC4500 device, it is much easier as the device provides reset mechanism.
What you need to do is set the register SCU_PRSET1.USIC2RS to assert reset on USIC2.
Then set the register SCU_PRCLR1.USIC2RS to de-assert reset on USIC2.
With this, USIC2 module will be reset.
0 Likes