I2C IRQ handler Implementation Part 1
In this article, let’s discuss I2C ISR handling. We have to implement two ISRs that is ISR1 and ISR2, as shown in Figure 1.
- ISR1: It is the interrupt handling for interrupts generated by I2C events. It can be named as I2C_EV_IRQHandling API.
- ISR2: It is the interrupt handling for interrupts generated by I2C errors. It can be named as I2C_ER_IRQHandling API.
Steps for implementation:
1. Go to the I2C_driver.h file of the project and create two more APIs, as shown in Figure 2. Both the APIs take only one parameter that is a handle.
2. Copy the prototype of both APIs and paste it at the end of the I2C_driver.c file, as shown in Figure 3.
3. Implement the I2C_EV_IRQHandling API: This API is implemented according to a couple of comments given in Figure 4.
I2C event interrupt may happen for various reasons. All the events in Figure 5 have the capacity to generate I2C event interrupt.
Some of the reasons for the occurrence of the I2C event interrupt are as follows (Figure 6):
- SB
- ADDR
- BTF
- STOP
- RXNE
- TXE
In the program, first, decode the reasons for the occurrence of the I2C event interrupt. The handle for the various events causing I2C event interrupt is as follows:
- Handle for interrupt generated by SB event (Figure 7):
- Confirm whether the SB flag is set or not.
- Create a couple of temporary variables, say temp1, temp2, and temp3.
- Remember that the SB event interrupt will happen only if the ITEVFEN control bit is enabled. So, first, make sure that whether the control bit ITEVFEN is set or not. To find out the state of the ITEVFEN bit, you have to read the control register 2. The state of this bit is stored in a temp1 variable by using temp1= pI2CHandle->pI2Cx->CR2 & (1 << I2C_CR2_ITEVFEN) statement, as shown in Figure 7.
- Check for the state of ITBUFEN using pI2CHandle->pI2Cx->CR2 & (1 << ITBUFEN) statement.
- Refer to the status register to check whether the SB bit is set or not. The value of the SB bit is stored in the variable temp3 using pI2CHandle->pI2Cx->SR1 & (1 << I2C_SR1_SB) statement.
- If both the temp1 and temp3 values are TRUE, then only the SB flag is set. Otherwise, the SB is not set, and the I2C event interrupt is happened because of some other reasons.
2. Handle for interrupt generated by ADDR event: Code is similar to the SB event, but the difference is you have to replace the SB with ADDR, as shown in Figure 8.
3. Handle for interrupt generated by BTF (Byte Transfer Finished) event is shown in Figure 9.
4. Handle for interrupt generated by STOPF event is as shown in Figure 10.
5. Handle for interrupt generated by TXE event:
- Confirm whether the TXE flag is set or not.
- Remember that the TXE event interrupt will happen only if both ITEVFEN and ITBUFEN control bits are enabled. Since it is necessary to check both control bits, the code should be modified, as shown in Figure 11.
6. Handle for interrupt generated by RXNE event: Code is similar to the TXE event, but the difference is you have to replace the TXE with RXNE, as shown in Figure 12.
Whenever an I2C event interrupt happens, the I2C_EV_IRQHandling function will get executed, where the reasons for the occurrence of the I2C event interrupt are decoded.