Open Channel

Once we have imported canlib.canlib to enumerate the connected Kvaser CAN devices, the next call is likely to be a call to openChannel, which returns a Channel object for the specific CAN circuit. This object is then used for subsequent calls to the library. The openChannel function’s first argument is the number of the desired channel, the second argument is modifier flags Open.

openChannel may raise several different exceptions, one of which is CanNotFound. This means that the channel specified in the first parameter was not found, or that the flags passed to openChannel is not applicable to the specified channel.

Open as CAN

No special Open modifier flag is needed in the flags argument to openChannel when opening a channel in CAN mode.

>>> from canlib import canlib
>>> canlib.openChannel(channel=0, flags=canlib.Open.EXCLUSIVE)
<canlib.canlib.channel.Channel object at 0x0000015B787EDA90>

Open as CAN FD

To open a channel in CAN FD mode, either CAN_FD or CAN_FD_NONISO needs to be given in the flags argument to openChannel.

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

>>> from canlib import canlib
>>> ch = canlib.openChannel(
...     channel=0,
...     flags=canlib.Open.CAN_FD | canlib.Open.EXCLUSIVE,
... )
>>> ch.close()

Close Channel

Closing a channel is done using close. If no other handles are referencing the same CANlib channel, the channel is taken off bus.

The CAN channel can also be opened and closed using a context manager:

>>> from canlib import canlib
>>> with canlib.openChannel(channel=1) as ch:
...     ...

Check Channel Capabilities

Channel specific information and capabilities are made available by reading attributes of an instance of type ChannelData.

The device clock frequency can be obtained via frequency():

>>> from canlib import canlib
>>> chd = canlib.ChannelData(channel_number=0)
>>> clock_info = chd.clock_info
>>> clock_info.frequency()
80000000

The capabilities of a channel can be obtained by reading attribute channel_cap and channel_cap_ex:

>>> from canlib import canlib
>>> chd = canlib.ChannelData(channel_number=0)
>>> chd.channel_cap
ChannelCap.IO_API|SCRIPT|LOGGER|SINGLE_SHOT|SILENT_MODE|CAN_FD_NONISO|CAN_FD|
TXACKNOWLEDGE|TXREQUEST|GENERATE_ERROR|ERROR_COUNTERS|BUS_STATISTICS|EXTENDED_CAN
>>> chd.channel_cap_ex[0]
ChannelCapEx.BUSPARAMS_TQ

A bitwise AND operator can be used to see if a channel has a specific capability.

>>> if (chd.channel_cap & canlib.ChannelCap.CAN_FD):
>>>   print("Channel has support for CAN FD!")
Channel has support for CAN FD!

The above printouts are just an example, and will differ for different devices and installed firmware.

Set CAN Bitrate

After opening the channel in classic CAN mode (see Open as CAN), use set_bus_params_tq to specify the bit timing parameters on the CAN bus. Bit timing parameters are packaged in an instance of type BusParamsTq. Note that the synchronization segment is excluded as it is always one time quantum long.

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

>>> from canlib import canlib
>>> ch = canlib.openChannel(channel=0)
>>> params = canlib.busparams.BusParamsTq(
...     tq=8,
...     phase1=2,
...     phase2=2,
...     sjw=1,
...     prescaler=20,
...     prop=3
... )
>>> ch.set_bus_params_tq(params)

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 set a specific bus speed, one can use calc_busparamstq, which returns a BusParamsTq object:

>>> calc_busparamstq(
... target_bitrate=470_000,
... target_sample_point=82,
... target_sync_jump_width=15.3,
... clk_freq=clock_info.frequency(),
... target_prop_tq=50,
... prescaler=2)
BusParamsTq(tq=85, prop=25, phase1=44, phase2=15, sjw=13, prescaler=2)

For users that are not interested in specifying individual bit timing parameters, CANlib also provides a set of default parameter settings for the most common bus speeds through the Bitrate class. The predefined bitrate constants may be set directly in the call to openChannel:

>>> ch = canlib.openChannel(channel=0, bitrate=canlib.Bitrate.BITRATE_500K)
Bit timing parameters for some of the most common bus speeds on a CAN device with an 80 MHz oscillator 1

tq

phase1

phase2

sjw

prop

prescaler

Sample point

Bitrate

BITRATE_10K

16

4

4

1

7

500

75%

10 kbit/s

BITRATE_50K

16

4

4

1

7

100

75%

50 kbit/s

BITRATE_62K

16

4

4

1

7

80

75%

62 kbit/s

BITRATE_83K

8

2

2

2

3

120

75%

83 kbit/s

BITRATE_100K

16

4

4

1

7

50

75%

100 kbit/s

BITRATE_125K

16

4

4

1

7

40

75%

125 kbit/s

BITRATE_125K

8

2

2

1

3

40

75%

250 kbit/s

BITRATE_500K

8

2

2

1

3

20

75%

500 kbit/s

BITRATE_1M

8

2

2

1

3

10

75%

1 Mbit/s

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

Set CAN FD Bitrate

After opening a channel in CAN FD mode (see Open as CAN FD), bit timing parameters for both the arbitration and data phases need to be set. This is done by a call to set_bus_params_tq, with two separate instances of type BusParamsTq as arguments.

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

>>> from canlib import canlib
>>> ch = canlib.openChannel(channel=0, flags=canlib.Open.CAN_FD)
>>> params_arbitration = canlib.busparams.BusParamsTq(
...     tq=80,
...     phase1=16,
...     phase2=16,
...     sjw=16,
...     prescaler=2,
...     prop=47
... )
>>> params_data = canlib.busparams.BusParamsTq(
...     tq=40,
...     phase1=31,
...     phase2=8,
...     sjw=8,
...     prescaler=2,
...     prop=0
... )
>>> ch.set_bus_params_tq(params_arbitration, params_data)

For users that are not interested in specifying individual bit timing parameters, CANlib also provides a set of default parameter settings for the most common bus speeds through the BitrateFD class. The predefined bitrates may be set directly in the call to openChannel:

>>> ch = canlib.openChannel(
...     channel=0,
...     flags=canlib.Open.CAN_FD,
...     bitrate=canlib.BitrateFD.BITRATE_500K_80P,
...     data_bitrate=canlib.BitrateFD.BITRATE_1M_80P,
... )

For CAN FD bus speeds other than the predefined BitrateFD, bit timing parameters have to be specified manually.

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

tq

phase1

phase2

sjw

prop

prescaler

Sample point

Bitrate

BITRATE_500K_80P

40

8

8

8

23

4

80%

500 kbit/s

BITRATE_1M_80P

40

8

8

8

23

2

80%

1 Mbit/s

BITRATE_2M_80P

20

15

4

4

0

2

80%

2 Mbit/s

BITRATE_4M_80P

10

7

2

2

0

2

80%

4 Mbit/s

BITRATE_8M_60P

5

2

2

1

0

2

60%

8 Mbit/s

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

CAN Driver Modes

Use setBusOutputControl to set the bus driver mode. This is usually set to NORMAL to obtain the standard push-pull type of driver. Some controllers also support 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.

>>> from canlib import canlib
>>> with canlib.openChannel(channel=1) as ch:
...     ch.setBusOutputControl(canlib.Driver.SILENT)
...     ...

NORMAL is set by default.

Legacy Functions

The following functions are still supported by canlib.

Set CAN Bitrate

setBusParams can be used to set the 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 getBusParamsFd can return bus parameter settings different than the ones supplied. Note however, that a successful call to setBusParamsFd 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.

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:

>>> ch.setBusParams(freq=125000, tseg1=4, tseg2=3, sjw=1, noSamp=1)

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

>>> ch.setBusParams(freq=111111, tseg1=5, tseg2=2, sjw=2, noSamp=1)

For full bit timing control, use set_bus_params_tq instead.

Set CAN FD Bitrate

After a channel has been opened in CAN FD mode, setBusParams, and setBusParamsFd 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 getBusParamsFd can return bus parameter settings different than the ones supplied. Note however, that a successful call to setBusParamsFd 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.

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

>>> ch.setBusParams(freq=500000, tseg1=63, tseg2=16, sjw=16, noSamp=1);
>>> ch.setBusParamsFd(freq_brs=1000000, tseg1_brs=31, tseg2_brs=8, sjw_brs=8);

For full bit timing control, use set_bus_params_tq instead.

1(1,2)

See Check Channel Capabilities for information on clock frequency.