Open Channel

Once we have called canInitializeLibrary() to enumerate the connected Kvaser CAN devices, the next call is likely to be a call to canOpenChannel(), which returns a handle to a specific CAN circuit. This handle is then used to all subsequent calls to the library. The canOpenChannel() function takes two arguments, the first of which is the number of the desired channel, the second argument is modifier flags canOPEN_xxx.

canOpenChannel() may return several different error codes, one of which is canERR_NOTFOUND. This means that the channel specified in the first parameter was not found, or that the flags passed to canOpenChannel() is not applicable to the specified channel.

Open as CAN

No special canOPEN_xxx modifier flag is needed in the flags argument to canOpenChannel() when opening a channel in CAN mode.

hnd = canOpenChannel(channel_number, 0);

Example. This example opens channel 0 for exclusive usage by this application.

if (hnd < 0) {
printf("Open failed, stat=%d\n", hnd);
}

When opening a channel as CAN, use canSetBusParamsTq() to specify bus parameters. Instructions and examples are found below.

Open as CAN FD

To open a channel in CAN FD mode, either canOPEN_CAN_FD or canOPEN_CAN_FD_NONISO needs to be given in the flags argument to canOpenChannel().

hnd = canOpenChannel(channel_number, canOPEN_CAN_FD);

Example. This example opens channel 0 in CAN FD mode for exclusive usage by this application.

if (hnd < 0) {
printf("Open failed, stat=%d\n", hnd);
}

When opening a channel as CAN FD, use canSetBusParamsFdTq() to specify bus parameters. Instructions and examples are found below.

Close Channel

Closing a channel is done using canClose(). If no other handles are referencing the same CANlib channel, the channel is taken off bus. The handle can not be used for further references to the channel, so any variable containing this handle should be set to canINVALID_HANDLE.

canStatus stat = canClose(hnd);
if (stat < 0) {
printf("Close failed.");
}

Check Channel Capabilities

Channel specific information and capabilities can be obtained by a call to canGetHandleData() or canGetChannelData(). What information to receive from the channel is specified by passing an argument of type canCHANNELDATA_xxx.

Example. Make a query for the device clock frequency.

canStatus stat;
kvClockInfo clockInfo;
int frequency;
stat = canGetHandleData(hnd, canCHANNELDATA_CLOCK_INFO, &clockInfo, sizeof(clockInfo));
if (stat != canOK) {
printf("Close failed.");
}
frequency = clockInfo.numerator / clockInfo.denominator * pow(10, clockInfo.power_of_ten);
printf("clock frequency = %d\n", frequency);

Example. Print the upper and lower bit timing limits for a device associated with a specific CAN channel.

canStatus stat;
stat = canGetChannelData(channel, canCHANNELDATA_BUS_PARAM_LIMITS, &limits, sizeof(limits));
if (stat != canOK) {
printf("Get bus parameter limits limits failed.");
}
printf ("\n------- Arbitration limits -------\n");
printf (" phase1 min: %d max: %d\n", limits.arbitration_min.phase1, limits.arbitration_max.phase1);
printf (" phase2 min: %d max: %d\n", limits.arbitration_min.phase2, limits.arbitration_max.phase2);
printf (" sjw min: %d max: %d\n", limits.arbitration_min.sjw, limits.arbitration_max.sjw);
printf (" prop min: %d max: %d\n", limits.arbitration_min.prop, limits.arbitration_max.prop);
printf (" prescaler min: %d max: %d\n", limits.arbitration_min.prescaler, limits.arbitration_max.prescaler);
printf ("\n---------- Data limits -----------\n");
printf (" phase1 min: %d max: %d\n", limits.data_min.phase1, limits.data_max.phase1);
printf (" phase2 min: %d max: %d\n", limits.data_min.phase2, limits.data_max.phase2);
printf (" sjw min: %d max: %d\n", limits.data_min.sjw, limits.data_max.sjw);
printf (" prop min: %d max: %d\n", limits.data_min.prop, limits.data_max.prop);
printf (" prescaler min: %d max: %d\n", limits.data_min.prescaler, limits.data_max.prescaler);

Obtain channel capabilities by passing argument canCHANNELDATA_CHANNEL_CAP and extended capabilities using flag canCHANNELDATA_CHANNEL_CAP_EX. Support for specific capabilities are tested by a bitwise AND operation with corresponding capability flags canCHANNEL_CAP_xxx, and canCHANNEL_CAP_EX_xxx.

Example. Check if channel has support for CAN FD, and setting bus speed and bit timing parameters using canSetBusParamsTq().

canStatus stat;
uint32_t cap;
uint64_t cap_ex[2];
stat = canGetHandleData(hnd, canCHANNELDATA_CHANNEL_CAP, &cap, sizeof(cap));
if (stat != canOK) {
printf("Get channel capabilities failed.");
}
if (cap & canCHANNEL_CAP_CAN_FD) {
printf("Channel has support for CAN FD.\n");
}
stat = canGetHandleData(hnd, canCHANNELDATA_CHANNEL_CAP_EX, &cap_ex, sizeof(cap_ex));
if (stat != canOK) {
printf("Get extended channel capabilities failed.");
}
printf("Channel has support for setting bitrate using canSetBusParamsTq().\n");
}

More examples of how to check capabilities can be found in example/c/channeldata.c

Set CAN Bitrate

After opening a channel in classic CAN mode (see Open as CAN), the bus speed can be set either by manually specifying bit timing parameters, or by using predefined bitrate constants.

Specifying Bit Timing Parameters

Use canSetBusParamsTq() to set the bit timing parameters on the CAN bus. Bit timing parameters are packaged in a struct kvBusParamsTq, note that the synchronization segment is excluded as it is always one time quantum long.

Example. To set the bus speed to 500 kbit/s on a CAN device with an 80 MHz oscillator:

kvBusParamsTq params = { 8, 2, 2, 1, 3, 20 };
stat = canSetBusParamsTq(hnd, params);
if (stat != canOK) {
printf("canSetBusParamsTq failed, status=%d\n", stat);
exit(1);
}

In the example a prescaler of 20 is used, resulting in each bit comprising of 160 time quanta (8 * 20). The nominal bus speed is given by 80 * 10^6 / (20 * 8) = 500 * 10^3.

If uncertain how to calculate bit timing parameters, appropriate values can be acquired using the Bit Timing Calculator for CAN FD. Note that in classic CAN mode, only the nominal bus parameters are of concern when using the Bus Bit Timing Calculator.

Using Predefined Bitrate Constants

For users that not are interested in specifying individual bit timing parameters, CANlib also provides a set of default parameter settings for the most common bus speeds through the canBITRATE_xxx constants. To set the bus speed using predefined bit rates, use canSetBusParams() with a canBITRATE_xxx constant as the second argument, and all trailing arguments set to zero.

Example. Setting the bus speed to 500 kbit/s:

stat = canSetBusParams(hnd, canBITRATE_500K, 0, 0, 0, 0, 0);
if (stat != canOK) {
printf("canSetBusParams failed, status=%d\n", stat);
exit(1);
}

Available predefined bitrate constants with corresponding bit timing parameters for a CAN device with an 80 MHz oscillator. [1]

tqphase1phase2sjwpropprescalerSample pointBitrate
canBITRATE_10K16441750075%10 kbit/s
canBITRATE_50K16441710075%50 kbit/s
canBITRATE_62K1644178075%62 kbit/s
canBITRATE_83K8222312075%83 kbit/s
canBITRATE_100K1644175075%100 kbit/s
canBITRATE_125K1644174075%125 kbit/s
canBITRATE_250K822134075%250 kbit/s
canBITRATE_500K822132075%500 kbit/s
canBITRATE_1M822131075%1 Mbit/s

For bus speeds other than the predefined canBITRATE_xxx constants, bit timing parameters have to be specified manually.

Set CAN FD Bitrate

After opening a channel in CAN FD mode (see Open as CAN FD), the bus speed can be set either by specifying bit timing parameters, or by using predefined bitrate constants.

Specifying Bit Timing Parameters

Use canSetBusParamsFdTq() to set the bit timing parameters on the CAN bus in CAN FD mode. Bit timing parameters for both the arbitration and data phases need to be set using two separate kvBusParamsTq structs.

Example. Set the arbitration bitrate to 500 kbit/s and the data phase bitrate to 1000 kbit/s, with sampling points at 80% on a device with an 80 MHz oscillator.

kvBusParamsTq paramsArb = { 80, 16, 16, 16, 47, 2 };
kvBusParamsTq paramsDat = { 40, 31, 8, 8, 0, 2 };
stat = canSetBusParamsFdTq(hnd, paramsArb, paramsDat);
if (stat != canOK) {
printf("canSetBusParamsFdTq failed, status=%d\n", stat);
exit(1);
}

If uncertain how to calculate bit timing parameters, appropriate values can be acquired using the Bit Timing Calculator for CAN FD

Using Predefined Bitrate Constants

For users that are not interested in specifying individual bit timing parameters, CANlib provides a set of default parameter settings for the most common bus speeds through the canFD_BITRATE_xxx constants. Use canSetBusParams() to set the arbitration phase bus speed, and canSetBusParamsFd() to set the data phase bus speed.

Example. Set the arbitration phase bitrate to 500 kbit/s, with sampling point at 80% and the data phase bitrate to 1000 kbit/s, with sampling point at 80%.

stat1 = canSetBusParams(hnd, canFD_BITRATE_500K_80P, 0, 0, 0, 0, 0);
stat2 = canSetBusParamsFd(hnd, canFD_BITRATE_1M_80P, 0, 0, 0);
if (stat1 != canOK || stat2 canOK) {
printf("Setting bus parameters failed, stat1s=%d stat2=%d\n", stat1, stat2);
exit(1);
}

Available predefined bitrate constants with corresponding bit timing parameters for a CAN FD device with an 80 MHz oscillator. [1]

tqphase1phase2sjwpropprescalerSample pointBitrate
canFD_BITRATE_500K_80P4088823480%500 kbt/s
canFD_BITRATE_1M_80P4088823280%1 Mbit/s
canFD_BITRATE_2M_80P208447280%2 Mbit/s
canFD_BITRATE_2M_60P208843260%2 Mbit/s
canFD_BITRATE_4M_80P107220280%4 Mbit/s
canFD_BITRATE_8M_80P107210180%8 Mbit/s
canFD_BITRATE_8M_70P106310170%8 Mbit/s
canFD_BITRATE_8M_60P52210260%8 Mbit/s

For bus speeds other than the predefined canFD_BITRATE_xxx constants, bit timing parameters have to be specified manually.

CAN Driver Modes

Use canSetBusOutputControl() to set the bus driver mode. This is usually set to canDRIVER_NORMAL to obtain the standard push-pull type of driver. Some controllers also support canDRIVER_SILENT which makes the controller receive only, not transmit anything, not even ACK bits. This might be handy for e.g. when listening to a CAN bus without interfering.

canDRIVER_NORMAL is set by default.

Code Sample

See how-to/c/openChannels.c for code sample.

Legacy Functions

The following functions are still supported in canlib.

Set CAN Bitrate

canSetBusParams() can be used to set CAN bus parameters, including bitrate, the position of the sampling point etc, they are also described in most CAN controller data sheets. Depending on device and installed firmware, the requested parameters may be subject to scaling in order to accommodate device specific restrictions. As such, reading back bus parameters using canGetBusParams() can return bus parameter settings different than the ones supplied. Note however, that a successful call to canSetBusParams() will always result in the requested bit rate being set on the bus, along with bus parameters that for all intents and purposes are equivalent to the ones requested.

Example. Set the speed to 125 kbit/s, each bit comprising 8 (= 1 + 4 + 3) quanta, the sampling point occurs at 5/8 of a bit; SJW = 1; one sampling point.

stat = canSetBusParams(hnd, 125000, 4, 3, 1, 1, 0);
if (stat != canOK) {
printf("canSetBusParams failed, status=%d\n", stat);
exit(1);
}

Example. Set the speed to 111111 kbit/s, the sampling point to 75%, the SJW to 2 and the number of samples to 1:

stat = canSetBusParams(hnd, 111111, 5, 2, 2, 1, 0);

For full bit timing control, use canSetBusParamsTq() instead.

Set CAN FD Bitrate

After a channel has been opened in CAN FD mode, canSetBusParams() and canSetBusParamsFd() can be used to set the arbitration and data phase bitrates respectively. Depending on device and installed firmware, the requested parameters may be subject to scaling in order to accommodate device specific restrictions. As such, reading back bus parameters using canGetBusParamsFd() can return bus parameter settings different than the ones supplied. Note however, that a successful call to canSetBusParamsFd() will always result in the requested bit rate being set on the bus, along with bus parameters that for all intents and purposes are equivalent to the ones requested.

Example. Set the nominal bitrate to 500 kbit/s and the data phase bitrate to 1000 kbit/s, with sampling points at 80%.

stat1 = canSetBusParams(hnd, 500000L, 63, 16, 16, 1, 0);
stat2 = canSetBusParamsFd(hnd, 1000000L, 31, 8, 8);
if (stat1 != canOK || stat2 != canOK) {
printf("Setting bus parameters failed, stat1=%d, stat2=%d\n", stat1, stat2);
exit(1);
}

For full bit timing control, use canSetBusParamsFdTq() instead.


[1] See Check Channel Capabilities for information on clock frequency.