3.2.5 DIAG_CAN
The DIAG_CAN module is designed to verify the correct functionality of the CAN Controller through a set of C function calls.
The DIAG_CAN software test API is mapped to the following safety mechanisms:
| Function | Diagnostic Mechanism | Use Case | Elapsed Time (μs)~ |
|---|---|---|---|
| DIAG_CAN_CrcCheck() | CAN_CHECKSUM / CAN_ERROR | POST | 312.35 |
| DIAG_CAN_Disable() | CAN_DISABLE | POST / OnDemand | 44.62 |
| DIAG_CAN_Enable() | CAN_ENABLE | POST / OnDemand | 11 |
| DIAG_CAN_Initialize() | NONE | POST | 10 |
| DIAG_CAN_Marching1Loopback() | DIAG_CAN_LOOPBACK CAN_INTERRUPTS | OnDemand | 400 |
| DIAG_CAN_RxBuffer() | CAN_RX_BUFFER | POST / OnDemand | 404.85 |
| DIAG_CAN_SFRReset() | SFR_RESET_STATE | POST | 31.08 |
| DIAG_CAN_SFRWriteRead() | SFR_WRITE_READ | POST / OnDemand | 37.77 |
| DIAG_CAN_TimeStamps() | CAN_TIMESTAMP | POST | 418.5 |
| DIAG_CAN_Transmit1() | CAN_LOOPBACK | POST | 386 |
| DIAG_CAN_TransmitMarching1() |
CAN_INTERRUPTS | POST | 361 |
#define DIAG_CAN0 1U
#define DIAG_CAN1 2U /* not available for E18A */
typedef uint32_t DIAG_CAN_PERIPHS;
#define DIAG_CAN_PERIPHS_CHECK_VALUE \
(DIAG_CAN0|DIAG_CAN1)
#define NUM_CANS 2U // number of CAN peripherals
typedef enum
{
CAN_NO_LOOPBACK,
CAN_INT_LOOPBACK,
CAN_EXT_LOOPBACK,
} DIAG_CAN_LOOPBACK;
Configuring the Diagnostic
CAN_DIAG must be configured as illustrated to supported to support all diagnostics:

Note: if testing both, then both checkboxes should be
checked.
CAN Safe-Plib must be configured as illustrated to supported to support all diagnostics:

Run-time Pre-requisites
DIAG_CAN_Initialize should be executed before DIAG_CAN_Enable
DIAG_CAN_SFRRead should be executed before DIAG_CAN_SFRWriteRead
Using the Diagnostic
#include "definitions.h"
// SFR testing
DIAG_TEST_STATUS DIAG_CAN_SFRPost (DIAG_CAN_PERIPHS can_periph)
{
DIAG_TEST_STATUS result = DIAG_TEST_NOT_EXECUTED;
if (!(can_periph & DIAG_CAN_PERIPHS_CHECK_VALUE))
{
DIAG_LogSpecialError(DIAG_BAD_PARAMETER);
return DIAG_TEST_FAILED;
}
int j,k;
j = 1;
for (k=0; k < NUM_CANS; k++)
{
if (can_periph & j)
{
result = DIAG_TEST_FAILED;
result = DIAG_CAN_SFRReset(j,NULL,0,false);
if (result != DIAG_TEST_PASSED)
{
break;
}
result = DIAG_CAN_SFRWriteRead(j,NULL,0,false);
if (result != DIAG_TEST_PASSED)
{
break;
}
}
j *= 2; // increment to next bit
}
return result;
}
// Post testing
DIAG_TEST_STATUS DIAG_CAN_Post (DIAG_CAN_PERIPHS can_periph)
{
DIAG_TEST_STATUS result = DIAG_TEST_NOT_EXECUTED;
if (!(can_periph & DIAG_CAN_PERIPHS_CHECK_VALUE))
{
DIAG_LogSpecialError(DIAG_BAD_PARAMETER);
return DIAG_TEST_FAILED;
}
int j,k;
j = 1;
for (k=0; k < NUM_CANS; k++)
{
if (can_periph & j)
{
result = DIAG_CAN_Enable(j);
if (result == DIAG_TEST_PASSED)
{
result = DIAG_CAN_Disable(j);
if (result == DIAG_TEST_PASSED)
{
result = DIAG_CAN_Initialize(j, 0x469, CAN_INT_LOOPBACK);
if (result == DIAG_TEST_PASSED)
{
result = DIAG_CAN_Transmit1(j);
if (result == DIAG_TEST_PASSED)
{
result = DIAG_CAN_TransmitMarching1(j);
}
if (result == DIAG_TEST_PASSED)
{
result = DIAG_CAN_CrcCheck(j, true);
}
if (result == DIAG_TEST_PASSED)
{
result = DIAG_CAN_TimeStamps(j);
}
if (result != DIAG_TEST_PASSED)
{
break;
}
}
}
}
}
j *= 2; // increment to next bit
}
return result;
}