Jetson/AGX Xavier CAN

From eLinux.org
Jump to: navigation, search

This page describes how to enable and verify CAN in Linux on Jetson AGX Xavier.
Jetson AGX Xavier exposes two CAN instances: CAN0, CAN1.

Hardware

Jetson Xavier Pin, Tegra Signal, Pin Type: https://developer.nvidia.com/embedded/dlc/jetson-xavier-oem-product-designguide, section 12.4
Pin exposed on Carrier board: http://developer.nvidia.com/embedded/dlc/jetson-xavier-developer-kit-carrier-board-spec, section 3.3
Note, there is not CAN transceiver on Jetson AGX Xavier module and Carrier board

Software

This section includes CAN Driver Enable, CAN Verification and Socket CAN Program.
To enable CAN driver, two steps below are needed:

  1. Update Pinmux
  2. Enable CAN by installing kernel modules and configuring the interface

CAN Driver Enable

Update Pinmux

To comply with Raspi 40-pin standard, the CAN I/O pins on Jetson AGX Xavier are configured to have GPIO functionality. To configure pins to CAN functionality, pinmux configure file needs to be changed.

Locate Pinmux configure file

PINMUX_CONFIG variable in $JETPACK_ROOT/Xavier/Linux_for_Tegra/jetson-xavier.conf defines pinmux configure file name like below.
The pinmux configure file locates at $JETPACK_ROOT/Xavier/Linux_for_Tegra/bootloader/t186ref/BCT/.

#!/bin/bash

# Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#  * Neither the name of NVIDIA CORPORATION nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# p2972-0000-devkit.conf: configuration for T194 Silicon

source "${LDK_DIR}/p2972-0000.conf.common";
PINMUX_CONFIG="tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg";

Modify Pinmux

Set pinmux in configure file, in this case, it is $JETPACK_ROOT/Xavier/Linux_for_Tegra/bootloader/t186ref/BCT/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg.
Below is the change. pinmux.0x0c303000 and pinmux.0x0c303008 are for CAN1 while pinmux.0x0c303010 and pinmux.0x0c303018 are for CAN0.
Or follow How to Update Pinmux to use tools to generate new configure file, the latter way is recommended.

diff --git a/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg b/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg
index df43561..c61e80d 100644
--- a/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg
+++ b/tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg
@@ -322,10 +322,10 @@ pinmux.0x0243d010 = 0x00000059; # spi1_cs0_pz6: rsvd1, pull-up, tristate-enable,
 pinmux.0x0243d050 = 0x00000059; # spi1_cs1_pz7: rsvd1, pull-up, tristate-enable, input-enable, lpdr-disable
 pinmux.0x0c301010 = 0x00000059; # safe_state_pee0: rsvd1, pull-up, tristate-enable, input-enable, io_high_voltage-disable, lpdr-disable
 pinmux.0x0c301038 = 0x00000058; # power_on_pee4: rsvd0, pull-up, tristate-enable, input-enable, lpdr-disable
-pinmux.0x0c303000 = 0x0000c055; # can1_dout_paa0: rsvd1, pull-down, tristate-enable, input-enable
-pinmux.0x0c303008 = 0x0000c055; # can1_din_paa1: rsvd1, pull-down, tristate-enable, input-enable
-pinmux.0x0c303010 = 0x0000c059; # can0_dout_paa2: rsvd1, pull-up, tristate-enable, input-enable
-pinmux.0x0c303018 = 0x0000c059; # can0_din_paa3: rsvd1, pull-up, tristate-enable, input-enable
+pinmux.0x0c303000 = 0x0000c400; # can1_dout_paa0: rsvd1, pull-down, tristate-enable, input-enable
+pinmux.0x0c303008 = 0x0000c458; # can1_din_paa1: rsvd1, pull-down, tristate-enable, input-enable
+pinmux.0x0c303010 = 0x0000c400; # can0_dout_paa2: rsvd1, pull-up, tristate-enable, input-enable
+pinmux.0x0c303018 = 0x0000c458; # can0_din_paa3: rsvd1, pull-up, tristate-enable, input-enable
 pinmux.0x0c303020 = 0x0000c000; # can0_stb_paa4: rsvd0, tristate-disable, input-disable
 pinmux.0x0c303028 = 0x0000c000; # can0_en_paa5: rsvd0, tristate-disable, input-disable
 pinmux.0x0c303030 = 0x0000c058; # can0_wake_paa6: rsvd0, pull-up, tristate-enable, input-enable

Flash device

 $ cd $JETPACK_ROOT/Xavier/Linux_for_Tegra/
 $ sudo ./flash.sh jetson-xavier mmcblk0p1

Enable CAN

Install CAN modules

By default, CAN is compiled as module. In this case, run below command on board to install modules.

 $ sudo modprobe can
 $ sudo modprobe can-raw
 $ sudo modprobe can-dev
 $ sudo modprobe mttcan

Set CAN

Now, two CAN instances are initialized: can0, can1. Choose can0 as an example.

Before setting CAN, run below command to make sure CAN is down.

 $ sudo ifconfig can0 down

Set CAN bit rate (in this case 1000000) and bring CAN up.

 $ sudo ip link set can0 up type can bitrate 1000000

Now, can0 is ready to use.

CAN Verification

Install can-utils

Follow https://elinux.org/Can-utils to install can-utils on Jetson AGX Xavier.

Send CAN Message

Below command can send CAN message:

 $ cansend can0 123#abcdabcd

Below command can generate random CAN messages:

 $ cangen -v can0

Receive CAN Message

Below command can dump messages received by can0:

 $ candump can0

Socket CAN Program

https://en.wikipedia.org/wiki/SocketCAN has a working example of the SocketCAN API.