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:

Table 3-6. 
FunctionDiagnostic MechanismUse CaseElapsed Time (μs)~
DIAG_CAN_CrcCheck()CAN_CHECKSUM / CAN_ERRORPOST312.35
DIAG_CAN_Disable()CAN_DISABLEPOST / OnDemand44.62
DIAG_CAN_Enable()CAN_ENABLEPOST / OnDemand11
DIAG_CAN_Initialize()NONEPOST10
DIAG_CAN_Marching1Loopback()DIAG_CAN_LOOPBACK CAN_INTERRUPTSOnDemand400
DIAG_CAN_RxBuffer()CAN_RX_BUFFERPOST / OnDemand404.85
DIAG_CAN_SFRReset()SFR_RESET_STATEPOST31.08
DIAG_CAN_SFRWriteRead()SFR_WRITE_READPOST / OnDemand37.77
DIAG_CAN_TimeStamps()CAN_TIMESTAMPPOST418.5
DIAG_CAN_Transmit1()CAN_LOOPBACKPOST386
DIAG_CAN_TransmitMarching1()

CAN_INTERRUPTS

POST361
#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; 
}