Open prometheans152 opened 2 days ago
I suggest you don't close I2C in Tx/Rx API. Don't call I2C_DisableInt(i2c); I2C_Close(i2c); to close I2C, if you still want to use them next time. By the way, you also don't need to re-open it. You may refer I2C protocol in TRM and use Scop to monitor the transer on line to check what's going on. M051 TRM: [https://www.[nuvoton.com/resource-files/TRM_M051(BN_DN_DE)_Series_EN_Rev1.03.pdf](https://www.nuvoton.com/resource-files/TRM_M051(BN_DN_DE)_Series_EN_Rev1.03.pdf)](M051 TRM)
in section 6.12.7.1 and 6.12.7.2, you could find the protocol flow of I2C.
I have already read it, and I designed my API based on Figure 6-82 and Figure 6-23.
I am currently stuck after a complete transmission (one TX and one RX). I am unable to execute the next transmission. I printed the I2C status after the transmission ended, and the status shows 0xF8.
Next, I modified the code to execute only one transmission. I connected an oscilloscope to observe the transmission process. I noticed that at the end of the transmission (P), the SCL keeps sending clock signals and doesn't stop.
The waveform is as shown in the photo.
The changes in the status code during the transmission process are shown in the picture. From my perspective, the status code changes match my expectations.
I modified my code to try sending only one TX, and after the TX is completed, I release the I2C. I also modified the interrupt code to send I2C_I2CON_STO_SI when the status code is 0x28, ending the transmission. (After ending, the status code becomes 0xF8, indicating that the bus is released.) Upon execution, I observed the status code changes as expected. After confirming that the status is 0xF8, I used an oscilloscope to measure and found that the SCL is still continuously sending clock signals. In my understanding, the Master has absolute control in the I2C communication. If the Master wants to end the transmission, the Slave cannot prevent it. However, in this issue, I actively instructed the communication to stop, but in reality, it didn’t stop (SCL keeps sending clock signals). I believe this is a problem. Or is there another standard method to stop the communication?
Hi,
I sugguest you to remove "disable interrupt" and close I2C from your code.
It is still not work, you may use our sample code I2C_Master and I2C_Slave to check your hardware environment. If the sample code running well, it means the hardware environment is ok. Next, you could modify the sample code for what you want step by step for easy to figure out what's going on.
I have already remove the code that disables interrupts and closes I2C. I tested under the condition of disabling interrupts and closing I2C for the previous two comments as well. The current issue is that after completing a transmission (issuing a P), the SCL continues to send clocks. However, at this moment, the status register indicates that the bus is idle (0xF8).
By the way, My program works fine when 'interrupts are disabled and I2C is closed,' but I feel it doesn't make sense. That's why I'm raising this issue.
Hi,
For continuse SCL, it may be casued by timing issue, that's why I sugguest you to verify the hardware environment by m051 sample code.
You may slow down the I2C clock, modify the pull up resistor value and try again. By the way, it is recommanded to enable Schmitt for I/O of I2C for better reliability. You may refer to TRM and search Px_MFP register to enable it.
Hi,
I have used the method of disabling interrupts and closing I2C to verify the hardware. In this state, I was able to successfully retrieve temperature and voltage data from the slave, and the data was correct. Do you think this method is not feasible?
My clock settings are shown in the diagram below. This was modified based on your example. I didn’t use XTL12M, so I switched to HIRC.
I modified the example (EEPROM) for testing, and the same issue occurred.
I referred to the I2C-related example in your sample code and wrote an I2C API. However, when I tested sending commands continuously, it got stuck after the first command (after setting the STA for the next command, no interrupt was received). I added an initialization for the I2C at the beginning of my API and a shutdown of the I2C at the end, and it started working properly.
I would like to ask if there is a way to perform normal transmission without repeatedly turning the I2C on and off. Doing it this way doesn’t make much sense. Here is my API:
Here is my code for continuous transmission: