Hi, to stabilize communication at I2C-Bus, I have added a "SW-Watchdog" function which prevents from stucking in while-loop, using DAVE 4.3.2
Step 1: Add SYSTIMER_0 to your application, refer to Infineon readme file attached
before mainloop:
uint32_t timer_1_of_8 = 0;
timer_1_of_8 = SYSTIMER_CreateTimer(50000, SYSTIMER_MODE_ONE_SHOT, SW_IRQ_1, NULL); //systimer for I2C, 50ms
now build a function:
//IRQ-Handler for SYSTIMER, initiated by function Soft_WDG_1 (checkout SYSTIMER_XMC45.PDF)
void SW_IRQ_1 (void *args)
{
flag_eject_at_I2C_NACK=1;
I2C_MASTER_AbortTransmit(&I2C_MASTER_0);
I2C_MASTER_AbortReceive(&I2C_MASTER_0);
I2C_MASTER_Init(&I2C_MASTER_0);
}
and the Software Watchdog function, which is called before writing or reading to/from I2C-Bus
//on_or_off: if 0:off; 1: on
void Soft_WDG_1 (bool on_or_off)
{
if(on_or_off)
{
SYSTIMER_StartTimer(timer_1_of_8);
}
else
{
SYSTIMER_StopTimer(timer_1_of_8);
}
}
// eanble error handling in DAVE I2C_Master_0 app and take same callback names as used by following functions:
//IRQ-Handler of I2C-MASTER-Interface initiated by DAVE end of transmit callback
void tx_callback_0(void)
{
tx_completion_0 = 1;
}
//IRQ-Handler of I2C-Interface MASTER initiated by DAVE end of receive callback
void rx_callback_0(void)
{
rx_completion_0 = 1;
}
//IRQ-Handler MASTER for detecting arbitration lost, initiated by DAVE
void I2C_ARB_Lost_IRQ_Handler_0 (void)
{
flag_I2C_NACK=1;
}
//IRQ-Handler MASTER for detecting errors, initiated by DAVE
void I2C_ERR_IRQ_Handler_0 (void)
{
flag_I2C_NACK=1;
}
//IRQ-Handler MASTER for detecting missing/not responding slave initiated by DAVE
void I2C_NACK_IRQ_Handler_0(void)
{
flag_I2C_NACK=1;
I2C_MASTER_AbortTransmit(&I2C_MASTER_0) ;// before init, abort transmit has to be executed
I2C_MASTER_SendStop(&I2C_MASTER_0);
I2C_MASTER_Init(&I2C_MASTER_0); // init I2C bus again to respond
}
now, I have embedded I2C_Routines by SW_WDG in my I2C-device file *.c
Soft_WDG_1(ON);
I2C_status = I2C_MASTER_Transmit(&I2C_MASTER_0,true,DevID,&mem_ address,1,false); //call by referenced value (mem_address)
while((tx_completion_0 == 0) && (flag_I2C_NACK == 0) && (flag_eject_at_I2C_NACK == 0)); // if NACK or error is responded, I2C-bus stucks
tx_completion_0 = 0; // this is executed, if all right on bus
Soft_WDG_1(OFF); // after 50ms abort I2C-communication, Close, init I2C-Bus by SW_IRQ_1
if(flag_I2C_NACK || flag_eject_at_I2C_NACK) // clear all flags
{
flag_I2C_NACK=0;
flag_eject_at_I2C_NACK=0;
return 0xFF; // error occured on bus
}
return(I2C_status); // zero is our success
This works fine and rescues program from Looping endless.
I hope, you could extract my idea and implement it in your app.
Unfortunately, Project has 15MB of zipped Code, so I couldnt provide you with DAVE-Projekt Code.
Best regards Matthias
Step 1: Add SYSTIMER_0 to your application, refer to Infineon readme file attached
before mainloop:
uint32_t timer_1_of_8 = 0;
timer_1_of_8 = SYSTIMER_CreateTimer(50000, SYSTIMER_MODE_ONE_SHOT, SW_IRQ_1, NULL); //systimer for I2C, 50ms
now build a function:
//IRQ-Handler for SYSTIMER, initiated by function Soft_WDG_1 (checkout SYSTIMER_XMC45.PDF)
void SW_IRQ_1 (void *args)
{
flag_eject_at_I2C_NACK=1;
I2C_MASTER_AbortTransmit(&I2C_MASTER_0);
I2C_MASTER_AbortReceive(&I2C_MASTER_0);
I2C_MASTER_Init(&I2C_MASTER_0);
}
and the Software Watchdog function, which is called before writing or reading to/from I2C-Bus
//on_or_off: if 0:off; 1: on
void Soft_WDG_1 (bool on_or_off)
{
if(on_or_off)
{
SYSTIMER_StartTimer(timer_1_of_8);
}
else
{
SYSTIMER_StopTimer(timer_1_of_8);
}
}
// eanble error handling in DAVE I2C_Master_0 app and take same callback names as used by following functions:
//IRQ-Handler of I2C-MASTER-Interface initiated by DAVE end of transmit callback
void tx_callback_0(void)
{
tx_completion_0 = 1;
}
//IRQ-Handler of I2C-Interface MASTER initiated by DAVE end of receive callback
void rx_callback_0(void)
{
rx_completion_0 = 1;
}
//IRQ-Handler MASTER for detecting arbitration lost, initiated by DAVE
void I2C_ARB_Lost_IRQ_Handler_0 (void)
{
flag_I2C_NACK=1;
}
//IRQ-Handler MASTER for detecting errors, initiated by DAVE
void I2C_ERR_IRQ_Handler_0 (void)
{
flag_I2C_NACK=1;
}
//IRQ-Handler MASTER for detecting missing/not responding slave initiated by DAVE
void I2C_NACK_IRQ_Handler_0(void)
{
flag_I2C_NACK=1;
I2C_MASTER_AbortTransmit(&I2C_MASTER_0) ;// before init, abort transmit has to be executed
I2C_MASTER_SendStop(&I2C_MASTER_0);
I2C_MASTER_Init(&I2C_MASTER_0); // init I2C bus again to respond
}
now, I have embedded I2C_Routines by SW_WDG in my I2C-device file *.c
Soft_WDG_1(ON);
I2C_status = I2C_MASTER_Transmit(&I2C_MASTER_0,true,DevID,&mem_ address,1,false); //call by referenced value (mem_address)
while((tx_completion_0 == 0) && (flag_I2C_NACK == 0) && (flag_eject_at_I2C_NACK == 0)); // if NACK or error is responded, I2C-bus stucks
tx_completion_0 = 0; // this is executed, if all right on bus
Soft_WDG_1(OFF); // after 50ms abort I2C-communication, Close, init I2C-Bus by SW_IRQ_1
if(flag_I2C_NACK || flag_eject_at_I2C_NACK) // clear all flags
{
flag_I2C_NACK=0;
flag_eject_at_I2C_NACK=0;
return 0xFF; // error occured on bus
}
return(I2C_status); // zero is our success
This works fine and rescues program from Looping endless.
I hope, you could extract my idea and implement it in your app.
Unfortunately, Project has 15MB of zipped Code, so I couldnt provide you with DAVE-Projekt Code.
Best regards Matthias