ECAN Library

mikroPascal PRO for dsPIC30/33 and PIC24 provides a library (driver) for working with the dsPIC33FJ and pic24HJ ECAN module.

ECAN is a very robust protocol that has error detection and signalling, self–checking and fault confinement. Faulty ECAN data and remote frames are re-transmitted automatically, similar to the Ethernet.

Data transfer rates depend on distance. For example, 1 Mbit/s can be achieved at network lengths below 40m while 250 Kbit/s can be achieved at network lengths below 250m. The greater distance the lower maximum bitrate that can be achieved . The lowest bitrate defined by the standard is 200Kbit/s. Cables used are shielded twisted pairs.

ECAN supports two message formats:

ECAN message format and DMA RAM buffer definiton can be found in the ECan_Defs.mpas header file located in the ECAN project folder. Read this file carefully and make appropriate adjustments for mcu in use. Also, if a new project is to be created this file has to be copied, adjusted and included into the project via include pragma directive with corresponding Search Path updating.

  Important :

Library Routines

ECANxDmaChannelInit

Prototype

function ECANxDmaChannelInit(DmaChannel : word; ChannelDir : word; DmaRamBuffAdd : word) : word;

Description

The function preforms initialization of the DMA module for ECAN.

Parameters
  • DmaChannel: DMA Channel number. Valid values: 0..7.
  • ChannelDir: transfer direction. Valid values: 1 (DMA RAM to peripheral) and 0 (peripheral to DMA RAM).
  • DmaRamBuffAdd: DMA RAM buffer address. DMA RAM location is MCU dependent, refer to datasheet for valid address range.
Returns

  • 0 - if DMA channel parameter is valid
  • 0x0001 - if DMA channel is already in use (busy)
  • 0xFFFF - if DMA channel parameter is invalid

Requires

The ECAN routines are supported only by MCUs with the ECAN module.

Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

Example
// channel 0 will transfer 8 words from DMA RAM at 0x4000 to ECAN1
ECAN1DmaChannelInit(0, 1, 0x4000);
Notes
  • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
  • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

ECANxSetOperationMode

Prototype

procedure ECANxSetOperationMode(mode : word; WAIT : word) ;

Description

Sets the ECAN module to requested mode.

Parameters
  • mode: ECAN module operation mode. Valid values: ECAN_OP_MODE constants. See ECAN_OP_MODE constants.
  • WAIT: ECAN mode switching verification request. If WAIT == 0, the call is non-blocking. The function does not verify if the ECAN module is switched to requested mode or not. Caller must use ECANxGetOperationMode to verify correct operation mode before performing mode specific operation. If WAIT != 0, the call is blocking – the function won’t “return” until the requested mode is set and no additional verification is necessary.
Returns

Nothing.

Requires

The ECAN routines are supported only by MCUs with the ECAN module.

Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

Example
// set the ECAN1 module into configuration mode (wait inside ECAN1SetOperationMode until this mode is set)
ECAN1SetOperationMode(_ECAN_MODE_CONFIG, 0xFF);
Notes
  • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
  • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

ECANxGetOperationMode

Prototype

function ECANxGetOperationMode() : word;

Description

The function returns current operation mode of the ECAN module. See ECAN_OP_MODE constants or device datasheet for operation mode codes.

Parameters

None.

Returns

Current operation mode.

Requires

The ECAN routines are supported only by MCUs with the ECAN module.

Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

Example
// check whether the ECAN1 module is in Normal mode and if it is do something.
if (ECAN1GetOperationMode() = _ECAN_MODE_NORMAL) then
begin
  ...
end
Notes
  • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
  • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

ECANxInitialize

Prototype

procedure ECANxInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, ECAN_CONFIG_FLAGS : word);

Description

Initializes the ECAN module.

The internal ECAN module is set to:

  • Disable ECAN capture
  • Continue ECAN operation in Idle mode
  • Abort all pending transmissions
  • Clear all transmit control registers
  • Fcan clock : Fcy (Fosc/2)
  • Baud rate is set according to given parameters
  • ECAN mode is set to Normal
  • Filter and mask registers remain unchanged

SAM, SEG2PHTS, WAKFIL and DBEN bits are set according to the ECAN_CONFIG_FLAGS value.

Parameters
  • SJW as defined in MCU's datasheet (ECAN Module)
  • BRP as defined in MCU's datasheet (ECAN Module)
  • PHSEG1 as defined in MCU's datasheet (ECAN Module)
  • PHSEG2 as defined in MCU's datasheet (ECAN Module)
  • PROPSEG as defined in MCU's datasheet (ECAN Module)
  • ECAN_CONFIG_FLAGS ECAN module configuration flags. Each bit corresponds to the appropriate ECAN module parameter. Should be formed out of predefined ECAN flag constants. See ECAN_CONFIG_FLAGS constants.
Returns

Nothing.

Requires

The ECAN routines are supported only by MCUs with the ECAN module.

Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

Example
// initialize the ECAN1 module with appropriate baud rate and message acceptance flags along with the sampling rules
var ecan_config_flags : word;
...  
ecan_config_flags := _ECAN_CONFIG_SAMPLE_THRICE    and   // Form value to be used
                     _ECAN_CONFIG_PHSEG2_PRG_ON    and   //  with ECANInitialize
                     _ECAN_CONFIG_XTD_MSG          and
                     _ECAN_CONFIG_MATCH_MSG_TYPE   and
                     _ECAN_CONFIG_LINE_FILTER_OFF; 

ECAN1Initialize(1, 3, 3, 3, 1, ecan_config_flags);  // initialize the ECAN1 module
Notes
  • ECAN mode NORMAL will be set on exit.
  • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
  • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

ECANxSelectTxBuffers

Prototype

function ECANxSelectTxBuffers(txselect : word) : word;

Description

The function designates the ECAN module's transmit buffers.

Parameters
  • txselect: transmit buffer select. By setting bits in the txselect lower byte corresponding buffers are enabled for transmition. The ECAN module supports up to 8 transmit buffers. Also, by clearing bits in the txselect lower byte corresponding buffers are enabled for reception.
Returns

  • 0 - if input parameter is valid
  • 0xFFFF - if input parameter is invalid

Requires

The ECAN routines are supported only by MCUs with the ECAN module.

Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

The ECAN module must be initialized. See the ECANxInitialize routine.

Example
// Buffers 0 and 2 are enabled for transmition:
ECAN1SelectTxBuffers(0x0005);
Notes
  • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
  • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

ECANxFilterDisable

Prototype

procedure ECANxFilterDisable(fltdis : word) ;

Description

The function disables receive filters.

Parameters
  • fltdis: filter disable selection parameter. Each bit corresponds to appropriate filter. By settung bit the corresponding filter is to be disabled.
Returns

Nothing.

Requires

The ECAN routines are supported only by MCUs with the ECAN module.

Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

The ECAN module must be initialized. See the ECANxInitialize routine.

Example
// Filters 0, 4, 8, 12 are to be disabled: 
ECAN1FilterDisable(0x1111);
Notes
  • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
  • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

ECANxFilterEnable

Prototype

procedure ECANxFilterEnable(flten : word);

Description

The function enables receive filters.

Parameters
  • flten: filter enable selection parameter. Each bit corresponds to appropriate filter. By setting bit the corresponding filter will be enabled.
Returns

Nothing.

Requires

The ECAN routines are supported only by MCUs with the ECAN module.

Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

The ECAN module must be initialized. See the ECANxInitialize routine.

Example
// Filters 0, 4, 8, 12 are to be enabled:
ECAN1FilterEnable(0x1111);
Notes
  • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
  • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

ECANxSetBufferSize

Prototype

function ECANxSetBufferSize(Ecan1BuffSize : word) : word;

Description

The function configures the total number of receive and transmit buffers in DMA RAM.

Parameters
  • Ecan1BuffSize: Number of ECAN DMA RAM receive and transmit buffers. Valid values: 4, 6, 8, 12, 16, 24, 32. Each buffer is 16 bytes long.
Returns

  • 0 - if input parameter is valid
  • 0xFFFF - if input parameter is invalid

Requires

The ECAN routines are supported only by MCUs with the ECAN module.

Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

The ECAN module must be initialized. See the ECANxInitialize routine.

Example
// DMA RAM will have 16 rx+tx buffers
ECAN1SetBufferSize(16);
Notes
  • The same value should be used for DMA RAM buffer definition in the ECan_Defs.mpas header file located in the ECAN project folder.
  • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
  • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
  • ECANxSetBaudRate

    Prototype

    procedure ECANxSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, ECAN_CONFIG_FLAGS : word);

    Description

    Sets ECAN module baud rate. Due to complexity of the ECAN protocol, you can not simply force the bps value. Instead, use this function when ECAN is in Config mode. Refer to datasheet for details.

    SAM, SEG2PHTS and WAKFIL bits are set according to the ECAN_CONFIG_FLAGS value.

    Parameters
    • SJW as defined in MCU's datasheet (ECAN Module)
    • BRP as defined in MCU's datasheet (ECAN Module)
    • PHSEG1 as defined in MCU's datasheet (ECAN Module)
    • PHSEG2 as defined in MCU's datasheet (ECAN Module)
    • PROPSEG as defined in MCU's datasheet (ECAN Module)
    • ECAN_CONFIG_FLAGS ECAN module configuration flags. Each bit corresponds to the appropriate ECAN module parameter. Should be formed out of predefined ECAN flag constants. See ECAN_CONFIG_FLAGS constants
    Returns

    Nothing.

    Requires

    The ECAN routines are supported only by MCUs with the ECAN module.

    Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

    The ECAN module must be in Config mode, otherwise the function will be ignored. See ECANxSetOperationMode.

    Example
    // set required baud rate and sampling rules
    var ecan_config_flags : word;
    ...  
    ECAN1SetOperationMode(_ECAN_MODE_CONFIG,0xFF);              // set CONFIGURATION mode (ECAN1 module mast be in config mode for baud rate settings)
    
    ecan_config_flags := _ECAN_CONFIG_SAMPLE_THRICE     and      // Form value to be used
                         _ECAN_CONFIG_PHSEG2_PRG_ON     and      //  with ECAN1SetBaudRate
                         _ECAN_CONFIG_XTD_MSG           and
                         _ECAN_CONFIG_MATCH_MSG_TYPE    and
                         _ECAN_CONFIG_LINE_FILTER_OFF;
    									 
    ECAN1SetBaudRate(1, 3, 3, 3, 1, ecan_config_flags);        // set ECAN1 module baud rate
    Notes
    • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
    • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

    ECANxSetMask

    Prototype

    procedure ECANxSetMask(ECAN_MASK : word; val : longint; ECAN_CONFIG_FLAGS : word);

    Description

    The function configures appropriate mask for advanced message filtering.

    Parameters
    • ECAN_MASK: ECAN module mask number. Valid values: ECAN_MASK constants. See ECAN_MASK constants.
    • val: mask register value. This value is bit-adjusted to appropriate buffer mask registers
    • ECAN_CONFIG_FLAGS: selects type of messages to filter. Valid values:
      • _ECAN_CONFIG_ALL_VALID_MSG,
      • _ECAN_CONFIG_MATCH_MSG_TYPE & _ECAN_CONFIG_STD_MSG,
      • _ECAN_CONFIG_MATCH_MSG_TYPE & _ECAN_CONFIG_XTD_MSG.
      See ECAN_CONFIG_FLAGS constants.
    Returns

    Nothing.

    Requires

    The ECAN routines are supported only by MCUs with the ECAN module.

    Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

    The ECAN module must be in Config mode, otherwise the function will be ignored. See ECANxSetOperationMode.

    Example
    // set appropriate filter mask and message type value
    ECAN1SetOperationMode(_ECAN_MODE_CONFIG,0xFF);              // set CONFIGURATION mode (ECAN1 module must be in config mode for mask settings)
    
    // Set all mask0 bits to 1 (all filtered bits are relevant):
    // Note that -1 is just a cheaper way to write 0xFFFFFFFF.
    // Complement will do the trick and fill it up with ones.
    ECAN1SetMask(_ECAN_MASK_0, -1, _ECAN_CONFIG_MATCH_MSG_TYPE & _ECAN_CONFIG_XTD_MSG);
    
    Notes
    • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
    • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

    ECANxSetFilter

    Prototype

    procedure ECANxSetFilter(ECAN_FILTER : word; val : longint; ECAN_FILTER_MASK : word; ECAN_FILTER_RXBUFF : word; ECAN_CONFIG_FLAGS : word) ;

    Description

    The function configures and enables appropriate message filter.

    Parameters
    • ECAN_FILTER: ECAN module filter number. Valid values: ECAN_FILTER constants. See ECAN_FILTER constants.
    • val: filter register value. This value is bit-adjusted to appropriate filter registers
    • ECAN_FILTER_MASK: mask register corresponding to filter. Valid values: ECAN_MASK constants. See ECAN_MASK constants.
    • ECAN_FILTER_RXBUFF: receive buffer corresponding to filter. Valid values: ECAN_RX_BUFFER constants. See ECAN_RX_BUFFER constants.
    • ECAN_CONFIG_FLAGS: selects type of messages to filter. Valid values: _ECAN_CONFIG_XTD_MSG and _ECAN_CONFIG_STD_MSG. See ECAN_CONFIG_FLAGS constants.
    Returns

    Nothing.

    Requires

    The ECAN routines are supported only by MCUs with the ECAN module.

    Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

    The ECAN module must be in Config mode, otherwise the function will be ignored. See ECANxSetOperationMode.

    Example
    // set appropriate filter value and message type
    ECAN1SetOperationMode(_ECAN_MODE_CONFIG,0xFF);                  // set CONFIGURATION mode (ECAN1 module must be in config mode for filter settings)
    
    // Set id of filter 10 to 3, mask2, receive buffer 7, extended messages:
    ECAN1SetFilter(_ECAN_FILTER_10, 3, _ECAN_MASK_2, _ECAN_RX_BUFFER_7, _ECAN_CONFIG_XTD_MSG);
    Notes
    • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
    • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

    ECANxRead

    Prototype

    function ECANxRead(var id : longint; var data: array[8] of byte; var dataLen : word; var ECAN_RX_MSG_FLAGS : word) : word;

    Description

    If at least one full Receive Buffer is found, it will be processed in the following way:

    • Message ID is retrieved and stored to location pointed by the id pointer
    • Message data is retrieved and stored to array pointed by the data pointer
    • Message length is retrieved and stored to location pointed by the dataLen pointer
    • Message flags are retrieved and stored to location pointed by the ECAN_RX_MSG_FLAGS pointer

    Parameters
    • id: message identifier address
    • data: an array of bytes up to 8 bytes in length
    • dataLen: data length address
    • ECAN_RX_MSG_FLAGS: message flags address. For message receive flags format refer to the ECAN_RX_MSG_FLAGS constants. See ECAN_RX_MSG_FLAGS constants.
    Returns

    • 0 if none of Receive Buffers is full
    • 0xFFFF if at least one of Receive Buffers is full (message received)

    Requires

    The ECAN routines are supported only by MCUs with the ECAN module.

    Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

    The ECAN module must be in a mode in which receiving is possible. See ECANxSetOperationMode.

    Example
    // check the ECAN1 module for received messages. If any was received do something. 
    var msg_rcvd, rx_flags, data_len : word;
        data : array[8] of byte;
        msg_id : longint;
    ...
    ECAN1SetOperationMode(_ECAN_MODE_NORMAL,0xFF);                  // set NORMAL mode (ECAN1 module must be in a mode in which receiving is possible)
    ...
    rx_flags := 0;                                                 // clear message flags
    if (msg_rcvd = ECAN1Read(msg_id, data, data_len, rx_flags)) then
    begin
      ...
    end;
    Notes
    • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
    • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

    ECANxWrite

    Prototype

    function ECANxWrite(id : longint; var Data : array[8] of byte; DataLen, ECAN_TX_MSG_FLAGS : word) : word;

    Description

    If at least one empty Transmit Buffer is found, the function sends message in the queue for transmission.

    Parameters
    • id: ECAN message identifier. Valid values: all 11 or 29 bit values, depending on message type (standard or extended)
    • Data: data to be sent
    • DataLen: data length. Valid values: 0..8
    • ECAN_TX_MSG_FLAGS: message flags. Valid values: ECAN_TX_MSG_FLAGS constants. See ECAN_TX_MSG_FLAGS constants.
    Returns

    • 0 if all Transmit Buffers are busy
    • 0xFFFF if at least one Transmit Buffer is empty and available for transmition

    Requires

    The ECAN routines are supported only by MCUs with the ECAN module.

    Microcontroller must be connected to ECAN transceiver which is connected to the ECAN bus.

    The ECAN module must be in a mode in which transmission is possible. See ECANxSetOperationMode.

    Example
    // send message extended ECAN message with appropriate ID and data
    var tx_flags : word;
        data : array[8] of byte;
        msg_id : longint;
    ...
    ECAN1SetOperationMode(_ECAN_MODE_NORMAL,0xFF);      // set NORMAL mode (ECAN1 must be in a mode in which transmission is possible)
    
    tx_flags := _ECAN_TX_PRIORITY_0   and            
                _ECAN_TX_XTD_FRAME    and             
                _ECAN_TX_NO_RTR_FRAME;                   // set message flags
    ECAN1Write(msg_id, data, 1, tx_flags);
    Notes
    • ECAN library routine require you to specify the module you want to use. To select the desired ECAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
    • Number of ECAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

    ECAN Constants

    There is a number of constants predefined in the ECAN library. You need to be familiar with them in order to be able to use the library effectively. Check the example at the end of the chapter.

    ECAN_OP_MODE Constants

    The ECAN_OP_MODE constants define ECAN operation mode. The routine ECANxSetOperationMode expect one of these as their argument:

    const
        _ECAN_MODE_BITS        : word = 0x00E0;   // Use this to access opmode  bits
        _ECAN_MODE_NORMAL      : word = 0x00;
        _ECAN_MODE_DISABLE     : word = 0x01;
        _ECAN_MODE_LOOP        : word = 0x02;
        _ECAN_MODE_LISTEN      : word = 0x03;
        _ECAN_MODE_CONFIG      : word = 0x04;
        _ECAN_MODE_LISTEN_ALL  : word = 0x07;
    

    ECAN_CONFIG_FLAGS Constants

    The ECAN_CONFIG_FLAGS constants define flags related to the ECAN module configuration. The routines ECANxInitialize and ECANxSetBaudRate expect one of these (or a bitwise combination) as their argument:

    const
        _ECAN_CONFIG_DEFAULT         : word = 0xFF;   // 11111111
    
        _ECAN_CONFIG_PHSEG2_PRG_BIT  : word = 0x01;
        _ECAN_CONFIG_PHSEG2_PRG_ON   : word = 0xFF;   // XXXXXXX1
        _ECAN_CONFIG_PHSEG2_PRG_OFF  : word = 0xFE;   // XXXXXXX0
    
        _ECAN_CONFIG_LINE_FILTER_BIT : word = 0x02;
        _ECAN_CONFIG_LINE_FILTER_ON  : word = 0xFF;   // XXXXXX1X
        _ECAN_CONFIG_LINE_FILTER_OFF : word = 0xFD;   // XXXXXX0X
    
        _ECAN_CONFIG_SAMPLE_BIT      : word = 0x04;
        _ECAN_CONFIG_SAMPLE_ONCE     : word = 0xFF;   // XXXXX1XX
        _ECAN_CONFIG_SAMPLE_THRICE   : word = 0xFB;   // XXXXX0XX
    
        _ECAN_CONFIG_MSG_TYPE_BIT    : word = 0x08;
        _ECAN_CONFIG_STD_MSG         : word = 0xFF;   // XXXX1XXX
        _ECAN_CONFIG_XTD_MSG         : word = 0xF7;   // XXXX0XXX
    
        _ECAN_CONFIG_MATCH_TYPE_BIT  : word = 0x20;
        _ECAN_CONFIG_ALL_VALID_MSG   : word = 0xDF;   // XX0XXXXX
        _ECAN_CONFIG_MATCH_MSG_TYPE  : word = 0xFF;   // XX1XXXXX
    

    You may use bitwise and to form config word out of these values. For example:

    Copy Code To ClipboardCopy Code To Clipboard
    init := _ECAN_CONFIG_SAMPLE_THRICE    and
            _ECAN_CONFIG_PHSEG2_PRG_ON    and
            _ECAN_CONFIG_STD_MSG          and
            _ECAN_CONFIG_MATCH_MSG_TYPE   and
            _ECAN_CONFIG_LINE_FILTER_OFF;
    ...
    ECAN1Initialize(1, 1, 3, 3, 1, init);   // initialize ECAN1

    ECAN_TX_MSG_FLAGS Constants

    ECAN_TX_MSG_FLAGS are flags related to transmission of ECAN message. The routine ECANxWrite expect one of these (or a bitwise combination) as their argument:

    const
        _ECAN_TX_PRIORITY_BITS : word = 0x03;
        _ECAN_TX_PRIORITY_0    : word = 0xFC;   // XXXXXX00
        _ECAN_TX_PRIORITY_1    : word = 0xFD;   // XXXXXX01
        _ECAN_TX_PRIORITY_2    : word = 0xFE;   // XXXXXX10
        _ECAN_TX_PRIORITY_3    : word = 0xFF;   // XXXXXX11
    
        _ECAN_TX_FRAME_BIT     : word = 0x08;
        _ECAN_TX_STD_FRAME     : word = 0xFF;   // XXXXX1XX
        _ECAN_TX_XTD_FRAME     : word = 0xF7;   // XXXXX0XX
    
        _ECAN_TX_RTR_BIT       : word = 0x40;
        _ECAN_TX_NO_RTR_FRAME  : word = 0xFF;   // X1XXXXXX
        _ECAN_TX_RTR_FRAME     : word = 0xBF;   // X0XXXXXX
    

    You may use bitwise and to adjust the appropriate flags. For example:

    Copy Code To ClipboardCopy Code To Clipboard
    (* form value to be used with CANSendMessage: *)
    send_config := _ECAN_TX_PRIORITY_0 and
                  _ECAN_TX_XTD_FRAME  and
                  _ECAN_TX_NO_RTR_FRAME;
    ...
    ECAN1SendMessage(id, data, 1, send_config);

    ECAN_RX_MSG_FLAGS Constants

    ECAN_RX_MSG_FLAGS are flags related to reception of ECAN message. If a particular bit is set then corresponding meaning is TRUE or else it will be FALSE.

    const
        _ECAN_RX_FILTER_BITS : word = 0x000F; // Use this to access filter bits
        _ECAN_RX_FILTER_0    : word = 0x00;   // filter0 match
        _ECAN_RX_FILTER_1    : word = 0x01;   // filter1 match
        _ECAN_RX_FILTER_2    : word = 0x02;   // ...
        _ECAN_RX_FILTER_3    : word = 0x03;
        _ECAN_RX_FILTER_4    : word = 0x04;
        _ECAN_RX_FILTER_5    : word = 0x05;
        _ECAN_RX_FILTER_6    : word = 0x06;
        _ECAN_RX_FILTER_7    : word = 0x07;
        _ECAN_RX_FILTER_8    : word = 0x08;
        _ECAN_RX_FILTER_9    : word = 0x09;
        _ECAN_RX_FILTER_10   : word = 0x0A;
        _ECAN_RX_FILTER_11   : word = 0x0B;
        _ECAN_RX_FILTER_12   : word = 0x0C;
        _ECAN_RX_FILTER_13   : word = 0x0D;
        _ECAN_RX_FILTER_14   : word = 0x0E;   // ...
        _ECAN_RX_FILTER_15   : word = 0x0F;   // filter15 match
    
        _ECAN_RX_OVERFLOW    : word = 0x10;   // Set if Overflowed else cleared
        _ECAN_RX_INVALID_MSG : word = 0x20;   // Set if invalid else cleared
        _ECAN_RX_XTD_FRAME   : word = 0x40;   // Set if XTD message else cleared
        _ECAN_RX_RTR_FRAME   : word = 0x80;   // Set if RTR message else cleared
    

    You may use bitwise and to extract received message status. For example:

    Copy Code To ClipboardCopy Code To Clipboard
    if (MsgFlag and _ECAN_RX_OVERFLOW <> 0) then
    begin
      ...
      // Receiver overflow has occurred.
      // We have lost our previous message.
    end

    ECAN_MASK Constants

    The ECAN_MASK constants define mask codes. The routine ECANxSetMask expect one of these as their argument:

    Copy Code To ClipboardCopy Code To Clipboard
    const
        _ECAN_MASK_0 : word = 0;
        _ECAN_MASK_1 : word = 1;
        _ECAN_MASK_2 : word = 2;
    

    ECAN_FILTER Constants

    The ECAN_FILTER constants define filter codes. The routine ECANxSetFilter expect one of these as their argument:

    Copy Code To ClipboardCopy Code To Clipboard
    const
        _ECAN_FILTER_0  : word =  0;
        _ECAN_FILTER_1  : word =  1;
        _ECAN_FILTER_2  : word =  2;
        _ECAN_FILTER_3  : word =  3;
        _ECAN_FILTER_4  : word =  4;
        _ECAN_FILTER_5  : word =  5;
        _ECAN_FILTER_6  : word =  6;
        _ECAN_FILTER_7  : word =  7;
        _ECAN_FILTER_8  : word =  8;
        _ECAN_FILTER_9  : word =  9;
        _ECAN_FILTER_10 : word = 10;
        _ECAN_FILTER_11 : word = 11;
        _ECAN_FILTER_12 : word = 12;
        _ECAN_FILTER_13 : word = 13;
        _ECAN_FILTER_14 : word = 14;
        _ECAN_FILTER_15 : word = 15;
    

    ECAN_RX_BUFFER Constants

    The ECAN_RX_BUFFER constants define RX bufer codes codes. The routine ECANxSetFilter expect one of these as their argument:

    Copy Code To ClipboardCopy Code To Clipboard
    const
        _ECAN_RX_BUFFER_0  : word =  0,
        _ECAN_RX_BUFFER_1  : word =  1,
        _ECAN_RX_BUFFER_2  : word =  2,
        _ECAN_RX_BUFFER_3  : word =  3,
        _ECAN_RX_BUFFER_4  : word =  4,
        _ECAN_RX_BUFFER_5  : word =  5,
        _ECAN_RX_BUFFER_6  : word =  6,
        _ECAN_RX_BUFFER_7  : word =  7,
        _ECAN_RX_BUFFER_8  : word =  8,
        _ECAN_RX_BUFFER_9  : word =  9,
        _ECAN_RX_BUFFER_10 : word = 10,
        _ECAN_RX_BUFFER_11 : word = 11,
        _ECAN_RX_BUFFER_12 : word = 12,
        _ECAN_RX_BUFFER_13 : word = 13,
        _ECAN_RX_BUFFER_14 : word = 14,
        _ECAN_RX_BUFFER_15 : word = 15;
    

    Library Example

    The example demonstrates ECAN protocol. The 1st node initiates the communication with the 2nd node by sending some data to its address. The 2nd node responds by sending back the data incremented by 1. The 1st node then does the same and sends incremented data back to the 2nd node, etc.

    Code for the first ECAN node:

    Copy Code To ClipboardCopy Code To Clipboard
    program ECan_1st;
    
    uses ECAN_Defs;
    
    var Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags : word; // can flags
        Rx_Data_Len  : word;                                  // received data length in bytes
        RxTx_Data    : array[8] of byte;                      // can rx/tx data buffer
        Msg_Rcvd     : word;                                  // reception flag
        Rx_ID        : longint; 
    
    const ID_1st  : longint = 12111;        
    const ID_2nd  : longint = 3;                              // node IDs
    
    
    procedure C1Interrupt(); org 0x005A;                      // ECAN event iterrupt
      begin
              IFS2.C1IF := 0;                                 // clear ECAN interrupt flag
              if(C1INTF.TBIF <> 0) then                       // was it tx interrupt?
          C1INTF.TBIF := 0;                                   // if yes clear tx interrupt flag
    
        if(C1INTF.RBIF <> 0) then                             // was it rx interrupt?
                      C1INTF.RBIF := 0;                       // if yes clear rx interrupt flag
      end;
    
    begin
    
      // Set PLL : Fosc = ((Fin/PLLPRE)*PLLDIV)/PLLPOST ; (((10MHz/2)*32)/4) = 20MHz
      // refer the family datasheet for more details
      CLKDIV := CLKDIV and 0xFFE0;  //CLKDIVbits.PLLPRE = 0;
      PLLFBD := 0x1E;               //PLLFBDbits.PLLDIV = 0x1E;
      CLKDIV := CLKDIV and 0xFF3F;  //CLKDIVbits.PLLPOST = 1;
      CLKDIV := CLKDIV or 0x00C0;
    
      AD1PCFGH := 0xFFFF;                              //
      AD1PCFGL := 0xFFFF;                              // all ports digital I/O
      AD2PCFGL := 0xFFFF;                              //
    
      {* Clear Interrupt Flags *}
    
            IFS0 := 0;
            IFS1 := 0;
            IFS2 := 0;
            IFS3 := 0;
            IFS4 := 0;
    
      {* Enable ECAN1 Interrupt *}
    
            IEC2.C1IE   := 1;                          // enable ECAN1 interrupts
            C1INTE.TBIE := 1;                          // enable ECAN1 tx interrupt
            C1INTE.RBIE := 1;                          // enable ECAN1 rx interrupt
    
      PORTB    := 0;                                   // clear PORTB
      TRISB    := 0;                                   // set PORTB as output,
                                                       // for received message data displaying
    
      Can_Init_Flags := 0;                             //
      Can_Send_Flags := 0;                             // clear flags
      Can_Rcv_Flags  := 0;                             //
    
      Can_Send_Flags := _ECAN_TX_PRIORITY_0 and           // form value to be used
                        _ECAN_TX_XTD_FRAME and            // with CANSendMessage
                        _ECAN_TX_NO_RTR_FRAME;
    
      Can_Init_Flags := _ECAN_CONFIG_SAMPLE_THRICE and    // form value to be used
                        _ECAN_CONFIG_PHSEG2_PRG_ON and    // with CANInitialize
                        _ECAN_CONFIG_XTD_MSG and
                        _ECAN_CONFIG_MATCH_MSG_TYPE and
                        _ECAN_CONFIG_LINE_FILTER_OFF;
    
      RxTx_Data[0] := 9;                               // set initial data to be sent
      ECAN1DmaChannelInit(0, 1, @ECAN1RxTxRAMBuffer);  // init dma channel 0 for
                                                       // dma to ECAN peripheral transfer
      ECAN1DmaChannelInit(2, 0, @ECAN1RxTxRAMBuffer);  // init dma channel 2 for
                                                       // ECAN peripheral to dma transfer
      ECAN1Initialize(1, 3, 3, 3, 1, Can_Init_Flags);  // initialize ECAN
      ECAN1SetBufferSize(ECAN1RAMBUFFERSIZE);          // set number of rx+tx buffers in DMA RAM
    
      ECAN1SelectTxBuffers(0x000F);                    // select transmit buffers
                                                       // 0x000F = buffers 0:3 are transmit buffers
      ECAN1SetOperationMode(_ECAN_MODE_CONFIG,0xFF);   // set CONFIGURATION mode
    
      ECAN1SetMask(_ECAN_MASK_0, -1, _ECAN_CONFIG_MATCH_MSG_TYPE and _ECAN_CONFIG_XTD_MSG);        // set all mask1 bits to ones
      ECAN1SetMask(_ECAN_MASK_1, -1, _ECAN_CONFIG_MATCH_MSG_TYPE and _ECAN_CONFIG_XTD_MSG);        // set all mask2 bits to ones
      ECAN1SetMask(_ECAN_MASK_2, -1, _ECAN_CONFIG_MATCH_MSG_TYPE and _ECAN_CONFIG_XTD_MSG);        // set all mask3 bits to ones
      ECAN1SetFilter(_ECAN_FILTER_10, ID_2nd, _ECAN_MASK_2, _ECAN_RX_BUFFER_7, _ECAN_CONFIG_XTD_MSG);   // set id of filter10 to 2nd node ID
                                                                                                   // assign mask2 to filter10
                                                                                                   // assign buffer7 to filter10
      ECAN1SetOperationMode(_ECAN_MODE_NORMAL, 0xFF);    // set NORMAL mode
    
      ECAN1Write(ID_1st, RxTx_Data, 1, Can_Send_Flags);  // send initial message
    
      while TRUE do // endless loop
        begin
          Msg_Rcvd := ECAN1Read(Rx_ID , RxTx_Data , Rx_Data_Len, Can_Rcv_Flags); // receive message
          if ((Rx_ID = ID_2nd) and (Msg_Rcvd <> 0)) <> 0 then                    // if message received check id
            begin
              PORTB := RxTx_Data[0];                                             // id correct, output data at PORTB
              Inc(RxTx_Data[0]);
              Delay_ms(10);
              ECAN1Write(ID_1st, RxTx_Data, 1, Can_Send_Flags);                  // send incremented data back
            end;
        end;
    end.
    

    Code for the second ECAN node:

    Copy Code To ClipboardCopy Code To Clipboard
    program ECAN_2nd;
    
    uses ECan_Defs;
    
    var Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags : word; // can flags
        Rx_Data_Len  : word;                                  // received data length in bytes
        RxTx_Data    : array[8] of byte;                      // can rx/tx data buffer
        Msg_Rcvd     : word;                                  // reception flag
        Rx_ID        : longint;                               // can rx and tx ID
    
    const ID_1st  : longint = 12111;
    const ID_2nd  : longint = 3;                              // node IDs
    
    
    procedure C1Interrupt(); org 0x005A;                      // ECAN event iterrupt
      begin
              IFS2.C1IF := 0;                                 // clear ECAN interrupt flag
              if(C1INTF.TBIF <> 0) then                       // was it tx interrupt?
          C1INTF.TBIF := 0;                                   // if yes clear tx interrupt flag
    
        if(C1INTF.RBIF <> 0) then                             // was it rx interrupt?
                      C1INTF.RBIF := 0;                       // if yes clear rx interrupt flag
      end;
    
    
    begin
    
      // Set PLL : Fosc = ((Fin/PLLPRE)*PLLDIV)/PLLPOST ; (((10MHz/2)*32)/4) = 20MHz
      // refer the family datasheet for more details
      CLKDIV := CLKDIV and 0xFFE0;  //CLKDIVbits.PLLPRE = 0;
      PLLFBD := 0x1E;               //PLLFBDbits.PLLDIV = 0x1E;
      CLKDIV := CLKDIV and 0xFF3F;  //CLKDIVbits.PLLPOST = 1;
      CLKDIV := CLKDIV or 0x00C0;
    
      AD1PCFGH := 0xFFFF;                              //
      AD1PCFGL := 0xFFFF;                              // all ports digital I/O
      AD2PCFGL := 0xFFFF;                              //
    
      {* Clear Interrupt Flags *}
    
            IFS0 := 0;
            IFS1 := 0;
            IFS2 := 0;
            IFS3 := 0;
            IFS4 := 0;
    
      {* Enable ECAN1 Interrupt *}
    
            IEC2.C1IE   := 1;                          // enable ECAN1 interrupts
            C1INTE.TBIE := 1;                          // enable ECAN1 tx interrupt
            C1INTE.RBIE := 1;                          // enable ECAN1 rx interrupt
    
    
      PORTB    := 0;                                   // clear PORTB
      TRISB    := 0;                                   // set PORTB as output,
                                                       // for received message data displaying
    
      Can_Init_Flags := 0;                             //
      Can_Send_Flags := 0;                             // clear flags
      Can_Rcv_Flags  := 0;                             //
    
      Can_Send_Flags := _ECAN_TX_PRIORITY_0 and        // Form value to be used
                        _ECAN_TX_XTD_FRAME and         //  with CANSendMessage
                        _ECAN_TX_NO_RTR_FRAME;
    
      Can_Init_Flags := _ECAN_CONFIG_SAMPLE_THRICE and    // Form value to be used
                        _ECAN_CONFIG_PHSEG2_PRG_ON and    //  with CANInitialize
                        _ECAN_CONFIG_XTD_MSG and
                        _ECAN_CONFIG_MATCH_MSG_TYPE and
                        _ECAN_CONFIG_LINE_FILTER_OFF;
    
      ECAN1DmaChannelInit(0, 1, @ECAN1RxTxRAMBuffer);     // init dma channel 0 for
                                                          // dma to ECAN peripheral transfer
      ECAN1DmaChannelInit(2, 0, @ECAN1RxTxRAMBuffer);     // init dma channel 2 for
                                                          // ECAN peripheral to dma transfer
      ECAN1Initialize(1, 3, 3, 3, 1, Can_Init_Flags);     // initialize ECAN
      ECAN1SetBufferSize(ECAN1RAMBUFFERSIZE);             // set number of rx+tx buffers in DMA RAM
    
      ECAN1SelectTxBuffers(0x000F);                       // select transmit buffers
                                                          // 0x000F = buffers 0:3 are transmit buffers
      ECAN1SetOperationMode(_ECAN_MODE_CONFIG,0xFF);      // set CONFIGURATION mode
    
      ECAN1SetMask(_ECAN_MASK_0, -1, _ECAN_CONFIG_MATCH_MSG_TYPE and _ECAN_CONFIG_XTD_MSG);           // set all mask1 bits to ones
      ECAN1SetMask(_ECAN_MASK_1, -1, _ECAN_CONFIG_MATCH_MSG_TYPE and _ECAN_CONFIG_XTD_MSG);           // set all mask2 bits to ones
      ECAN1SetMask(_ECAN_MASK_2, -1, _ECAN_CONFIG_MATCH_MSG_TYPE and _ECAN_CONFIG_XTD_MSG);           // set all mask3 bits to ones
      ECAN1SetFilter(_ECAN_FILTER_10, ID_1st, _ECAN_MASK_2, _ECAN_RX_BUFFER_7, _ECAN_CONFIG_XTD_MSG); // set id of filter10 to 1st node ID
                                                                                                      // assign buffer7 to filter10
      ECAN1SetOperationMode(_ECAN_MODE_NORMAL,0xFF);    // set NORMAL mode
    
      while TRUE do
        begin
          Msg_Rcvd := ECAN1Read(Rx_ID, RxTx_Data, Rx_Data_Len, Can_Rcv_Flags);  // receive message
          if ((Rx_ID = ID_1st) and (Msg_Rcvd <> 0) <> 0) then                    // if message received check id
            begin
              PORTB := RxTx_Data[0];                                            // id correct, output data at PORTB
              Inc(RxTx_Data[0]);                                                // increment received data
              ECAN1Write(ID_2nd, RxTx_Data, 1, Can_Send_Flags);                  // send incremented data back
            end;
        end;
    end.
    

    HW Connection

    Example of interfacing ECAN transceiver with MCU and bus

    Example of interfacing ECAN transceiver with MCU and bus

    Copyright (c) 2002-2012 mikroElektronika. All rights reserved.
    What do you think about this topic ? Send us feedback!
    Want more examples and libraries? 
    Find them on LibStock - A place for the code