I encountered a very strange problem when using the RIIC module.When I ported the RIIC module to a project based on the FreeRTOS operating system, I could not communicate with the peripheral properly through the IIC, because I could not access the interrupt of the IIC module, and the IIC transfer was completed in the interrupt. Later,I added taskdelay function in the while loop while waiting for the IIC to be idle, and the IIC returned to normal. After verification, it was the interrupt setting problem. As long as the interrupt priority of the IIC module was raised to less than 15, the taskdelay function was not required for normal communication, and 15 was the lowest priority. When the IIC module priority is set to 15, the taskdelay function must be called to enter the interrupt. Why? Here are my program:
/***********************************************
Init
***********************************************/
INTC2MKRIIC0TI = 1U;
INTC2RFRIIC0TI = 0U;
INTC2TBRIIC0TI = 0U;
INTC2MKRIIC0TEI = 1U;
INTC2RFRIIC0TEI = 0U;
INTC2TBRIIC0TEI = 0U;
INTC2MKRIIC0RI = 1U;
INTC2RFRIIC0RI = 0U;
INTC2TBRIIC0RI = 0U;
INTC2MKRIIC0EE = 1U;
INTC2RFRIIC0EE = 0U;
INTC2TBRIIC0EE = 0U;
RIIC0.CR1.UINT32 &= 0xFFFFFF7FUL;
RIIC0.CR1.UINT32 |= 0x00000040UL;
RIIC0.CR1.UINT32 |= 0x00000080UL;
RIIC0.SER.UINT32 = 0x00000001UL;
RIIC0.MR1.UINT32 |= 0x00000040UL; /* 8MHz / 16 */
RIIC0.BRH.UINT32 = 30; /* 10kbps */RIIC0.BRL.UINT32 = 20;
// RIIC0.MR1.UINT32 |= 0x00000040UL; /* 40MHz / 8 */
// RIIC0.BRH.UINT32 = 0xF6U; /* 100kbps */// RIIC0.BRL.UINT32 = 0xF9U;
RIIC0.MR2.UINT32 = 0x00000006UL;
RIIC0.MR3.UINT32 = 0x00000010UL;
RIIC0.FER.UINT32 = 0x00000010UL;
RIIC0.IER.UINT32 = 0x000000E8UL;
/* Alternative function port settings *//* RIIC0SDA(P10_2:CN1D-110pin) 2'nd Alternative (output/input) *//* RIIC0SCL(P10_3:CN1D-109pin) 2'nd Alternative (output) */uint32_t reg32_value = PORTPODC10 | 0x0000000CUL;do{reg32_value = PORTPODC10 | 0x0000000CUL;PORTPPCMD10 = 0xA5U;PORTPODC10 = reg32_value;PORTPODC10 = (uint32_t)(~reg32_value);PORTPODC10 = reg32_value;} while (PORTPPROTS10 != 0x00000000UL);PORTPIPC10 &= 0xFFF3U; // must be 0PORTPBDC10 |= 0x000CU;PORTPFCAE10 &= 0xFFF3U;PORTPFCE10 &= 0xFFF3U;PORTPFC10 |= 0x000CU;PORTPMC10 |= 0x000CU;PORTPM10 &= 0xFFF3U;PORTPU10 |=0x000C;
/* I2C Bus Interface Internal ResetRIICnCR1 - I2C Bus Control Register 1b31:b 8 - Reserved set to 0b 7 ICE - I2C Bus Interface Enable - not change.b 6 IICRST - I2C Bus Interface Internal Reset - Clears the RIIC reset or internal reset. set to 0b 5 CLO - Extra SCL Clock Cycle Output - not change.b 4 SOWP - SCLO/SDAO Write Protect - not change.b 3 SCLO - SCL Output Control/Monitor - not change.b 2 SDAO - SDA Output Control/Monitor - not change.b 1 SCLI - SCL Line Monitor - not change.b 0 SDAI - SDA Line Monitor - not change. */RIIC0.CR1.UINT32 &= 0xFFFFFFBFUL;
SetTableBit((uint16*)R_ICRIIC0EE);UnmaskInterrupt((uint16*)R_ICRIIC0EE);
SetTableBit((uint16*)R_ICRIIC0RI);UnmaskInterrupt((uint16*)R_ICRIIC0RI);
SetTableBit((uint16*)R_ICRIICTI0);UnmaskInterrupt((uint16*)R_ICRIICTI0);
SetTableBit((uint16*)R_ICRIICTEI0);UnmaskInterrupt((uint16*)R_ICRIICTEI0);
This is my transmitter
void R_IIC_Master_Transmit(uint8 slave_addr, uint32 len , uint8 *transmission_data){
while( RIIC0.CR2.UINT32 & 0x00000080UL ); // Wait to a bus-free stateiic_prm.iic_state = ADDR_W_STATE;iic_prm.tx_data_p = transmission_data;iic_prm.tx_len = len;iic_prm.tx_count = 0UL;iic_prm.slave_addr = slave_addr;RIIC0.CR2.UINT32 |= 0x00000002UL; //Startup RIIC
}
This is my IIC Send
while ( R_IIC_GetState() != IDLE_STATE ){{
R_IIC_Master_Transmit(SlaveAddress, Size, DataPtr);while ( R_IIC_GetState() != IDLE_STATE ){
This program is modeled after demo When the priority is 15, the taskdelay function must be activated; otherwise, the IIC interrupt cannot be accessed. When the priority is less than 15, the IIC interrupt cannot be accessed without calling the taskdelay function. 15 is the lowest priority, and 0 is the highest priority.why?}}
This program is modeled after demo When the priority is 15, the taskdelay function must be activated; otherwise, the IIC interrupt cannot be accessed. When the priority is less than 15, the IIC interrupt can be accessed without calling the taskdelay function. 15 is the lowest priority, and 0 is the highest priority.why?}}
Please do not create multiple posts for the same issue.
Regards