Jetson/AGX Xavier CAN

From eLinux.org
< Jetson
Revision as of 23:47, 28 October 2018 by Mchi (talk | contribs) (Software)
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

Pin Information

Jetson Xavier Pin, Tegra Signal: 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

Software

This section includes CAN driver Enable, CAN Verification and the application sample code to communicate with CAN interface.
To enable CAN driver, two steps below are needed:

  1. Update Pinmux
  2. Enable CAN by loading 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.

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 Verificaion

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.