This is divided into four sections:
- Initialization
- Sending
- Receiving
- Finalization
The code shown here is condensed and not complete, please look at the source code.
Section: Initializing
Selecting CLASSIC CAN or CAN FD
Set the constant MyApp to either canFD or canCLASSIC CAN.
Set TX_MySelCh to the interface you want to use as sender.
Set RX_MySelCh to the interface you want to use as receiver.
All (almost) Kvaser CAN interfaces can be both senders and receivers at the same time. We select to use one as TX and one as RX in this example to make it easier to follow the code.
First we run three commands:
canInitializeLibrary()
canGetChannelData()
We know now how many interfaces we have and their names. We are now ready to open two of them.
canOpenChannel()
- Editing needed for Can FD!
CAN CLASSIC
TX_MyHnd := canOpenChannel(TX_MySelCh – 1, canOPEN_ACCEPT_VIRTUAL);
RX_MyHnd := canOpenChannel(RX_MySelCh – 1, canOPEN_ACCEPT_VIRTUAL);
CAN FD
TX_MyHnd := canOpenChannel(TX_MySelCh – 1, canOPEN_ACCEPT_VIRTUAL OR canOPEN_CAN_FD);
RX_MyHnd := canOpenChannel(RX_MySelCh – 1, canOPEN_ACCEPT_VIRTUAL OR canOPEN_CAN_FD);
It is important to use the FLAG: canOPEN_CAN_FD when opening a FD channel.
We are using combination of “canOPEN_ACCEPT_VIRTUAL OR canOPEN_CAN_FD” to open a virtual interface and to set the mode to FD.
The interfaces are opened and now we must set their parameters.
canSetBusParams() and canSetBusParamsFD()
- Editing and adding information needed for FD!
- It is possible to use other values than the predefined (not covered here).
CAN CLASSIC
Uses only canSetBusParams() together with the canBITRATE_xxx.
TX := canSetBusParams(TX_MyHnd, canBITRATE_500K, 0, 0, 0, 0, 0);
RX := canSetBusParams(RX_MyHnd, canBITRATE_500K, 0, 0, 0, 0, 0);
CAN FD
Uses canSetBusParams() and canSetBusParamsFD() together with the canFD_BITRATE_xxx.
TX := canSetBusParams(TX_MyHnd, canFD_BITRATE_500K_80P, 0, 0, 0, 0, 0);
RX := canSetBusParams(RX_MyHnd, canFD_BITRATE_500K_80P, 0, 0, 0, 0, 0);
TX := canSetBusParamsFD(TX_MyHnd, canFD_BITRATE_1M_80P, 0, 0, 0);
RX := canSetBusParamsFD(RX_MyHnd, canFD_BITRATE_1M_80P, 0, 0, 0);
- Please note, do NOT use the canBITRATE_xxx values for FD!
All parameters are now set and we are ready to go online so we end the initializing section by opening the bus and doing some cleaning.
canBusOn()
canFlushTransmitQueue()
canFlushReceiveQueue()
Section: Sending
We have activated the bus and the interfaces wait for us to do something. We shall now send one frame from one of our selected interfaces.
canWrite()
- Editing needed for CAN FD!
(We can use the commands canWrite() and canWriteWait() but we only use canWrite in this example.)
Recommendation: READ THE HELP!
CAN CLASSIC
BUF := ‘Hello!’;
id := 111;
dlc := 8; // For Classic CAN dlc can be at most 8*
Flag := canMSG_STD;
R := canWrite(TX_MyHnd, id, @BUF, dlc, Flag);
CAN FD
BUF := ‘Hello World!’;
id := 222;
dlc := 16; // for CAN FD dlc CAN be one of the following 0-8,12, 16, 20, 24, 32, 48, 64
Flag := canMSG_STD OR canFDMSG_FDF OR canFDMSG_BRS;
R := canWrite(TX_MyHnd, id, @BUF, dlc, Flag);
- New buffer size to hold up to 64 bytes
- Add canFDMSG_FDF to flag (Indicates that the frame is an FD frame)
- Add canFDMSG_BRS to flag (Indicate if frame should be sent with bit rate switch)
Please note that canFDMSG_BRS is optional. When adding the BRS flag, the data part is sent with the FD-bitrate instead of the arbitration bitrate.
It is still possible to send classic CAN frames even if you have enabled FD! Using only canMSG_STD or canMSG_EXT creates a classic frame.
Section: Receiving
canRead()
- Editing needed for CAN FD!
(There are four versions (at least) of canRead() that can be used for receiving FD traffic. We only use canRead() in this example, so we recommend that you read the ‘Help’ file!)
R := canRead(RX_MyHnd, id, @BUF, dlc, Flag, myTime);
We do not need to change anything in the read command, but …
- Make sure that the buffer has a minimum length of 64 bytes. Even if we don’t intend to send frames longer than 24 bytes, someone else might.
- Study the returned FLAG values, which contains some new values. They are a combination of the canMSG_xxx, canMSGERR_xxx and canFDMSG_xxx
Even if we are alone on the bus and we only sent one frame, the received frame might not be the one we expected. If, for example, the value canMSG_ERROR_FRAME is included in the Flag, then the frame is an error frame instead of our expected frame.
- Always check the returned value [R] and the returned Flag!
We have now received our own frame.
Section: Finalization
The finalization does not need editing.
canBusOff()
canClose()
canUnloadLibrary()