ECAN Library
mikroBasic 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:
- Standard format, with 11 identifier bits, and
- Extended format, with 29 identifier bits
ECAN message format and DMA RAM buffer definiton can be found in the ECan_Defs.mbas
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.

- ECAN buffers are located in DMA RAM, so two DMA channels are used for message transfer, one for each direction (ECAN->DMA RAM, DMA RAM->ECAN). See the ECANxDmaChannelInit routine.
- Consult CAN standard about CAN bus termination resistance.
- CAN library routines require you to specify the module you want to use. To select the desired CAN module, simply change the letter x in the routine prototype for a number from 1 to 2.
- Number of CAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Library Routines
- ECANxDmaChannelInit
- ECANxSetOperationMode
- ECANxGetOperationMode
- ECANxInitialize
- ECANxSelectTxBuffers
- ECANxFilterDisable
- ECANxFilterEnable
- ECANxSetBufferSize
- ECANxSetBaudRate
- ECANxSetMask
- ECANxSetFilter
- ECANxRead
- ECANxWrite
ECANxDmaChannelInit
Prototype |
sub function ECANxDmaChannelInit(dim DmaChannel as word, dim ChannelDir as word, dim DmaRamBuffAdd as word) as word |
---|---|
Description |
The function preforms initialization of the DMA module for ECAN. |
Parameters |
|
Returns |
|
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 |
|
ECANxSetOperationMode
Prototype |
sub procedure ECANxSetOperationMode(dim mode as word, dim WAIT as word) |
---|---|
Description |
Sets the ECAN module to requested mode. |
Parameters |
|
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 |
|
ECANxGetOperationMode
Prototype |
sub function ECANxGetOperationMode() as 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 ... end if |
Notes |
|
ECANxInitialize
Prototype |
sub procedure ECANxInitialize(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, ECAN_CONFIG_FLAGS as word) |
---|---|
Description |
Initializes the ECAN module. The internal ECAN module is set to:
|
Parameters |
|
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 dim ecan_config_flags as 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 |
|
ECANxSelectTxBuffers
Prototype |
sub function ECANxSelectTxBuffers(dim txselect as word) as word |
---|---|
Description |
The function designates the ECAN module's transmit buffers. |
Parameters |
|
Returns |
|
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 |
|
ECANxFilterDisable
Prototype |
sub procedure ECANxFilterDisable(dim fltdis as word) |
---|---|
Description |
The function disables receive filters. |
Parameters |
|
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 |
|
ECANxFilterEnable
Prototype |
sub procedure ECANxFilterEnable(dim flten as word) |
---|---|
Description |
The function enables receive filters. |
Parameters |
|
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 |
|
ECANxSetBufferSize
Prototype |
sub function ECANxSetBufferSize(dim Ecan1BuffSize as word) as word |
---|---|
Description |
The function configures the total number of receive and transmit buffers in DMA RAM. |
Parameters |
|
Returns |
|
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 |
ECan_Defs.mbas header file located in the ECAN project folder. |
ECANxSetBaudRate
Prototype |
sub procedure ECANxSetBaudRate(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, ECAN_CONFIG_FLAGS as 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.
|
Parameters |
|
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 dim ecan_config_flags as 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 |
|
ECANxSetMask
Prototype |
sub procedure ECANxSetMask(dim ECAN_MASK as word, dim val as longint, dim ECAN_CONFIG_FLAGS as word) |
---|---|
Description |
The function configures appropriate mask for advanced message filtering. |
Parameters |
|
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 and _ECAN_CONFIG_XTD_MSG) |
Notes |
|
ECANxSetFilter
Prototype |
sub procedure ECANxSetFilter(dim ECAN_FILTER as word, dim val as longint, dim ECAN_FILTER_MASK as word, dim ECAN_FILTER_RXBUFF as word, dim ECAN_CONFIG_FLAGS as word) |
---|---|
Description |
The function configures and enables appropriate message filter. |
Parameters |
|
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 |
|
ECANxRead
Prototype |
sub function ECANxRead(dim byref id as longint, dim byref data as byte[8], dim byref dataLen as word, dim byref ECAN_RX_MSG_FLAGS as word) as word |
---|---|
Description |
If at least one full Receive Buffer is found, it will be processed in the following way:
|
Parameters |
|
Returns |
|
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. dim msg_rcvd, rx_flags, data_len as word data as byte[8] msg_id as 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 ... end if |
Notes |
|
ECANxWrite
Prototype |
sub function ECANxWrite(dim id as longint, dim byref Data as byte[8], dim DataLen, ECAN_TX_MSG_FLAGS as word) as word |
---|---|
Description |
If at least one empty Transmit Buffer is found, the function sends message in the queue for transmission. |
Parameters |
|
Returns |
|
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 dim tx_flags as word data as byte[8] msg_id as 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 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 as word = 0x00E0 ' Use this to access opmode bits _ECAN_MODE_NORMAL as word = 0x00 _ECAN_MODE_DISABLE as word = 0x01 _ECAN_MODE_LOOP as word = 0x02 _ECAN_MODE_LISTEN as word = 0x03 _ECAN_MODE_CONFIG as word = 0x04 _ECAN_MODE_LISTEN_ALL as 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 as word = 0xFF ' 11111111 _ECAN_CONFIG_PHSEG2_PRG_BIT as word = 0x01 _ECAN_CONFIG_PHSEG2_PRG_ON as word = 0xFF ' XXXXXXX1 _ECAN_CONFIG_PHSEG2_PRG_OFF as word = 0xFE ' XXXXXXX0 _ECAN_CONFIG_LINE_FILTER_BIT as word = 0x02 _ECAN_CONFIG_LINE_FILTER_ON as word = 0xFF ' XXXXXX1X _ECAN_CONFIG_LINE_FILTER_OFF as word = 0xFD ' XXXXXX0X _ECAN_CONFIG_SAMPLE_BIT as word = 0x04 _ECAN_CONFIG_SAMPLE_ONCE as word = 0xFF ' XXXXX1XX _ECAN_CONFIG_SAMPLE_THRICE as word = 0xFB ' XXXXX0XX _ECAN_CONFIG_MSG_TYPE_BIT as word = 0x08 _ECAN_CONFIG_STD_MSG as word = 0xFF ' XXXX1XXX _ECAN_CONFIG_XTD_MSG as word = 0xF7 ' XXXX0XXX _ECAN_CONFIG_MATCH_TYPE_BIT as word = 0x20 _ECAN_CONFIG_ALL_VALID_MSG as word = 0xDF ' XX0XXXXX _ECAN_CONFIG_MATCH_MSG_TYPE as word = 0xFF ' XX1XXXXX
You may use bitwise and
to form config word out of these values. For example:
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 as word = 0x03 _ECAN_TX_PRIORITY_0 as word = 0xFC ' XXXXXX00 _ECAN_TX_PRIORITY_1 as word = 0xFD ' XXXXXX01 _ECAN_TX_PRIORITY_2 as word = 0xFE ' XXXXXX10 _ECAN_TX_PRIORITY_3 as word = 0xFF ' XXXXXX11 _ECAN_TX_FRAME_BIT as word = 0x08 _ECAN_TX_STD_FRAME as word = 0xFF ' XXXXX1XX _ECAN_TX_XTD_FRAME as word = 0xF7 ' XXXXX0XX _ECAN_TX_RTR_BIT as word = 0x40 _ECAN_TX_NO_RTR_FRAME as word = 0xFF ' X1XXXXXX _ECAN_TX_RTR_FRAME as word = 0xBF ' X0XXXXXX
You may use bitwise and
to adjust the appropriate flags. For example:
' 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 as word = 0x000F ' Use this to access filter bits _ECAN_RX_FILTER_0 as word = 0x00 ' filter0 match _ECAN_RX_FILTER_1 as word = 0x01 ' filter1 match _ECAN_RX_FILTER_2 as word = 0x02 ' ... _ECAN_RX_FILTER_3 as word = 0x03 _ECAN_RX_FILTER_4 as word = 0x04 _ECAN_RX_FILTER_5 as word = 0x05 _ECAN_RX_FILTER_6 as word = 0x06 _ECAN_RX_FILTER_7 as word = 0x07 _ECAN_RX_FILTER_8 as word = 0x08 _ECAN_RX_FILTER_9 as word = 0x09 _ECAN_RX_FILTER_10 as word = 0x0A _ECAN_RX_FILTER_11 as word = 0x0B _ECAN_RX_FILTER_12 as word = 0x0C _ECAN_RX_FILTER_13 as word = 0x0D _ECAN_RX_FILTER_14 as word = 0x0E ' ... _ECAN_RX_FILTER_15 as word = 0x0F ' filter15 match _ECAN_RX_OVERFLOW as word = 0x10 ' Set if Overflowed else cleared _ECAN_RX_INVALID_MSG as word = 0x20 ' Set if invalid else cleared _ECAN_RX_XTD_FRAME as word = 0x40 ' Set if XTD message else cleared _ECAN_RX_RTR_FRAME as word = 0x80 ' Set if RTR message else cleared
You may use bitwise and
to extract received message status. For example:
if (MsgFlag and _ECAN_RX_OVERFLOW <> 0) then ... ' Receiver overflow has occurred. ' We have lost our previous message. end if
ECAN_MASK Constants
The ECAN_MASK
constants define mask codes. The routine ECANxSetMask expect one of these as their argument:
const _ECAN_MASK_0 as word = 0 _ECAN_MASK_1 as word = 1 _ECAN_MASK_2 as word = 2
ECAN_FILTER Constants
The ECAN_FILTER
constants define filter codes. The routine ECANxSetFilter expect one of these as their argument:
const _ECAN_FILTER_0 as word = 0 _ECAN_FILTER_1 as word = 1 _ECAN_FILTER_2 as word = 2 _ECAN_FILTER_3 as word = 3 _ECAN_FILTER_4 as word = 4 _ECAN_FILTER_5 as word = 5 _ECAN_FILTER_6 as word = 6 _ECAN_FILTER_7 as word = 7 _ECAN_FILTER_8 as word = 8 _ECAN_FILTER_9 as word = 9 _ECAN_FILTER_10 as word = 10 _ECAN_FILTER_11 as word = 11 _ECAN_FILTER_12 as word = 12 _ECAN_FILTER_13 as word = 13 _ECAN_FILTER_14 as word = 14 _ECAN_FILTER_15 as 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:
const _ECAN_RX_BUFFER_0 as word = 0 _ECAN_RX_BUFFER_1 as word = 1 _ECAN_RX_BUFFER_2 as word = 2 _ECAN_RX_BUFFER_3 as word = 3 _ECAN_RX_BUFFER_4 as word = 4 _ECAN_RX_BUFFER_5 as word = 5 _ECAN_RX_BUFFER_6 as word = 6 _ECAN_RX_BUFFER_7 as word = 7 _ECAN_RX_BUFFER_8 as word = 8 _ECAN_RX_BUFFER_9 as word = 9 _ECAN_RX_BUFFER_10 as word = 10 _ECAN_RX_BUFFER_11 as word = 11 _ECAN_RX_BUFFER_12 as word = 12 _ECAN_RX_BUFFER_13 as word = 13 _ECAN_RX_BUFFER_14 as word = 14 _ECAN_RX_BUFFER_15 as 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:
program ECan_1st include ECAN_Defs dim Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags as word ' can flags Rx_Data_Len as word ' received data length in bytes RxTx_Data as byte[8] ' can rx/tx data buffer Msg_Rcvd as word ' reception flag Rx_ID as longint const ID_1st as longint = 12111 const ID_2nd as longint = 3 ' node IDs sub procedure C1Interrupt() org 0x005A ' ECAN event iterrupt 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 end if if(C1INTF.RBIF <> 0) then ' was it rx interrupt? C1INTF.RBIF = 0 ' if yes clear rx interrupt flag end if end sub main: ' Set PLL : Fosc = ((Fin/PLLPRE)*PLLDIV)/PLLPOST ; (((10MHz/2)*32)/4) = 20MHz ' refer the pic33 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 ' endless loop 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 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 if wend end.
Code for the second ECAN node:
program ECAN_2nd include ECAN_Defs dim Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags as word ' can flags Rx_Data_Len as word ' received data length in bytes RxTx_Data as byte[8] ' can rx/tx data buffer Msg_Rcvd as word ' reception flag Rx_ID as longint const ID_1st as longint = 12111 const ID_2nd as longint = 3 ' node IDs sub procedure C1Interrupt() org 0x005A ' ECAN event iterrupt 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 end if if(C1INTF.RBIF <> 0) then ' was it rx interrupt? C1INTF.RBIF = 0 ' if yes clear rx interrupt flag end if end sub main: ' Set PLL : Fosc = ((Fin/PLLPRE)*PLLDIV)/PLLPOST ; (((10MHz/2)*32)/4) = 20MHz ' refer the pic33 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 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 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 if wend end.
HW Connection
Example of interfacing ECAN transceiver with MCU and bus
What do you think about this topic ? Send us feedback!