This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
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.
Hello Gene,
Your configuration is fine. The received data should be equal to the transmitted data if the CAN core works as expected. There is no way to inject fault to CAN bus in digital loopback mode.
In loopback mode, the CAN core ignores the ACK errors.