Hello.
I'm trying to get CAN Error injection result through loop back test.
According to RM46L Safety Manual, I selected CAN10 ~ CAN13 (Stuff Error, Form Error, Acknowledge Error, Bit Error Detection).
But I can't get the result i want.
I implemented Error Injection in loop back mode.
And no Interrupt occured.
I'd like to get how to generate interrupt for those errors.
My code is follow by:
-----------------------------------------------------------------------------------------
void canInit(void)
{
canREG3->CTL = (uint32)0x00000000U
| (uint32)0x00000020U
| (uint32)((uint32)0x00000005U << 10U)
| 0x00020043U;
/** - Clear all pending error flags and reset current status */
canREG3->ES |= 0xFFFFFFFFU;
/** - Assign interrupt level for messages */
canREG3->INTMUXx[0U] = (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U;
canREG3->INTMUXx[1U] = (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U;
/** - Setup auto bus on timer period */
canREG3->ABOTR = (uint32)0U;
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG3->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG3->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
canREG3->IF1ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)0x0100FF00U & (uint32)0x1FFFFFFFU) << (uint32)0U);
canREG3->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000080U | (uint32)8U;
canREG3->IF1CMD = (uint8) 0xF8U;
canREG3->IF1NO = 1U;
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG3->IF2STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG3->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x04000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
canREG3->IF2ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
canREG3->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000080U | (uint32)8U;
canREG3->IF2CMD = (uint8) 0xF8U;
canREG3->IF2NO = 2U;
/** - Setup IF1 for data transmission
* - Wait until IF1 is ready for use
* - Set IF1 control byte
*/
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG3->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG3->IF1CMD = 0x87U;
/** - Setup IF2 for reading data
* - Wait until IF1 is ready for use
* - Set IF1 control byte
*/
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG3->IF2STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG3->IF2CMD = 0x17U;
/** - Setup bit timing
* - Setup baud rate prescaler extension
* - Setup TSeg2
* - Setup TSeg1
* - Setup sample jump width
* - Setup baud rate prescaler
*/
canREG3->BTR = (uint32)((uint32)4U << 16U) |
(uint32)((uint32)(3U - 1U) << 12U) |
(uint32)((uint32)((1U + 3U) - 1U) << 8U) |
(uint32)((uint32)(3U - 1U) << 6U) |
(uint32)(uint32)18U;
/** - CAN3 Port output values */
canREG3->TIOC = (uint32)((uint32)1U << 18U )
| (uint32)((uint32)0U << 17U )
| (uint32)((uint32)1U << 16U )
| (uint32)((uint32)1U << 3U )
| (uint32)((uint32)1U << 2U )
| (uint32)((uint32)1U << 1U );
canREG3->RIOC = (uint32)((uint32)1U << 18U )
| (uint32)((uint32)0U << 17U )
| (uint32)((uint32)0U << 16U )
| (uint32)((uint32)1U << 3U )
| (uint32)((uint32)0U << 2U )
| (uint32)((uint32)0U << 1U );
/** - Leave configuration and initialization mode */
canREG3->CTL &= ~(uint32)(0x00000041U);
/** @note This function has to be called before the driver can be used.\n
* This function has to be executed in privileged mode.\n
*/
/* USER CODE BEGIN (5) */
/* USER CODE END */
}
-----------------------------------------------------------------------------------------
My Test applicaton
{
uint8_t tx_data = 0x7E;
uint8_t rx_data = 0x00;
...................
canEnableStatusChangeNotification(canREG3);
canEnableloopback(canREG3, Internal_Lbk);
canTransmit(canREG3, canMESSAGE_BOX1, &tx_data);
while(!canIsRxMessageArrived(canREG3, canMESSAGE_BOX1))
{
}
canGetData(canREG3, canMESSAGE_BOX1, &rx_data);
........... wait for error interrupt ( If : s_u32CanLpbkComplete == 0xA5A5A5A5) ..........
canDisableloopback(canREG3);
canDisableStatusChangeNotification(canREG3);
}
-----------------------------------------------------------------------------------------
void canStatusChangeNotification(canBASE_t *node, uint32 notification)
{
uint32_t u32ErrorType = canGetLastError(canREG3);
switch (u32ErrorType)
{
case 1u: /* Stuff Error */
if(CheckBitStatus(canREG3->TEST, 4u) == 1u) /* Loopback Test Mode */
{
(void)SerialPutString("\r\n Loopback Test Mode : Stuff Error has Occured!!!\r\n");
s_u32CanLpbkComplete = 0xA5A5A5A5;
}
else
{
s_u16CanStufErrCnt = s_u16CanStufErrCnt + 1;
}
break;
case 2u: /* Format Error */
if(CheckBitStatus(canREG3->TEST, 4u) == 1u) /* Loopback Test Mode */
{
(void)SerialPutString("\r\n Loopback Test Mode : Format Error has Occured!!!\r\n");
s_u32CanLpbkComplete = 0xA5A5A5A5;
}
else
{
s_u16CanFormErrCnt = s_u16CanFormErrCnt + 1;
}
break;
case 3u: /* Acknowledge Error */
if(CheckBitStatus(canREG3->TEST, 4u) == 1u) /* Loopback Test Mode */
{
(void)SerialPutString("\r\n Loopback Test Mode : Acknowledge Error has Occured!!!\r\n");
s_u32CanLpbkComplete = 0xA5A5A5A5;
}
else
{
s_u16CanAckErrCnt = s_u16CanAckErrCnt + 1;
}
break;
case 4u: /* Bit Error */
case 5u: /* Bit Error */
if(CheckBitStatus(canREG3->TEST, 4u) == 1u) /* Loopback Test Mode */
{
(void)SerialPutString("\r\n Loopback Test Mode : Bit Error has Occured!!!\r\n");
s_u32CanLpbkComplete = 0xA5A5A5A5;
}
else
{
s_u16CanBitErrCnt = s_u16CanBitErrCnt + 1;
}
break;
default:
break;
}
return 1u;
}
-----------------------------------------------------------------------------------------
void can3HighLevelInterrupt(void)
{
uint32 value = canREG3->INT;
uint32 ES_value;
/* USER CODE BEGIN (53) */
/* USER CODE END */
if (value == 0x8000U)
{
/* Read Error and Status Register*/
ES_value = canREG3->ES;
/* Check for Error (PES, Boff, EWarn & EPass) captured */
if((ES_value & 0x1E0U) != 0U)
{
canErrorNotification(canREG3, ES_value & 0x1E0U);
}
else
{
/* Call General Can notification incase of RxOK, TxOK, PDA, WakeupPnd Interrupt */
#if 0
/* KimJinWook 2020.03.09 : Register Readback - START*/
canStatusChangeNotification(canREG3, ES_value & 0x61FU); /* Include LEC bits */
/* KimJinWook 2020.03.09 : Register Readback - END*/
#else
canStatusChangeNotification(canREG3, ES_value & 0x618U); /* Original Code */
#endif
}
}
else
{
/** - Setup IF1 for clear pending interrupt flag */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG3->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG3->IF1CMD = 0x08U;
/*SAFETYMCUSW 93 S MR: 6.1,6.2,10.1,10.2,10.3,10.4 <APPROVED> "LDRA Tool issue" */
canREG3->IF1NO = (uint8) value;
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG3->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG3->IF1CMD = 0x87U;
canMessageNotification(canREG3, value);
}
/* USER CODE BEGIN (54) */
/* USER CODE END */
}
-----------------------------------------------------------------------------------------
Note that CAN Rx/Tx is normal.
Please let me know my mistake what it is. (I need a manual or example code to implement Safety manual)
Best regards.
Gene.