I’m trying to get the can-app-rx-task working on a Jetson TX2 SPE. However I’m unable to receive any messages. I created a function, ivc_log, to help provide debugging data through the IVC data channel between the SPE and the Linux host and this is showing me that all of the messages I send to the SPE are being received with cmdid = 0x05 which is corresponding to MTTCAN_BERR_CHG


I’ve attached a diagram of the setup I’m working with. On the Jetson side, I have a 120 Ω termination resistor across CAN H/L. Then, I have both CAN H/L connected to the PEAK PCAN-USB Adapter along with the GND from the Jeton. From there, the PEAK is plugged into a laptop running Ubuntu 20.04 with can-utils installed.


I started with the demo code that goes along with the guide found here. I made a few modifications to get it working with our system and what we’re looking to do with the SPE as follows:

  • can-app.c
    • Enable CAN0 as TX and RX
    • Comment out the section that checks to make sure a single CAN controller is not both TX and RX
      • The demo code said that a single CAN controller can be used as both TX and RX
  • ‘soc/t18x/targer_specific.mk`
    • Set ENABLE_CAN_APP to 1
  • can-app-tx-task.c
    • Comment out the can_tx_event task and the can_process_txevent function
      • I found this would interfere with can-app-rx-task
    • Update CAN_TEST_DELAY to 100
    • Add vTaskDelay (CAN_TEST_DELAY*100) before the infinite while loop that transmits the messages
      • This gives the Linux host some time to boot up. Without it, the Linux host would not boot after flashing the Jetson with the SPE firmware
    • Remove all instances of can_test_transmit after the first one
      • I only want to send a normal CAN frame with an 11 bit identifier
    • Add an ivc_log function that utilizes the data channel between the SPE and the Linux host to be able to print debug messages
  • can-app-rx-task.c
    • Add an ivc_log function that utilizes the data channel between the SPE and the Linux host to be able to print debug messages
    • Comment out all printf statements form can_rx_test_print
      • Replace them with ivc_log ("CMD ID: 0x%02x, MSG ID: 0x%02x, Data Length: %d\r\n", cf->cmdid, msgid, dlen); so I can see cmdid, msgid, and dlen from the Linux host after a message is received
    • Comment out the if statement checking to only print messaged with a cmdid of MTTCAN_MSG_RX
      • I commented this out once I saw that I wasn’t seeing any of the messages sent to the Jetson being processed
        • I figured that the messages weren’t passing this check and I was correct since they’re all being read as MTTCAN_BERR_CHG

On the laptop, I set up the PEAK as a CAN interface with a baud rate of 500Kbps to match the default setting on the Jetson. I’ve also tested this at 1Mpbs and received similar results. When changing the baud rate on the Jetson, I updated ttcan_set_bitrate(ttcan, NBITRATE_PRESCALAR_500K, DBITRATE_PRESCALAR_2M); to ttcan_set_bitrate(ttcan, NBITRATE_PRESCALAR_1M, DBITRATE_PRESCALAR_2M); in tegra-can.c following a post that I saw here on the forums


For my initial test, I tried just TX by commenting out can_app_rx_task_init(CAN_RX_CONTROLLER); in can-app.c. From here, I was able to see the messages being sent from the SPE on my laptop by using candump

This showed that I was able to get TX from the SPE to work. So I then went to test RX. For this, I commented out can_app_tx_task_init(CAN_TX_CONTROLLER); in can-app.c. Once the SPE firmware was flashed to the Jetson, I sent messages from my laptop using the command cansend 0A5#12

Using the ivc_log function, I checked the information the SPE was reading from the message:

  • cmdid: 0x05
  • msgid: 0x00
  • Data Length: 20

I’ve had similar results using different messages as well, such as: cansend 0A5#AA55,cansend 0A5#, and cansend 000#12

From tegra-can.h, I can see that a cmdid of 0x05 corresponds to MTTCAN_MSG_BERR_CHG. Upon further testing, I found that all RX messages on the SPE were being seen with this cmdid. I believe this is corresponding to a bus error, but I’m not sure what could be causing this error.

I’ve also attached an image from my oscilloscope that is showing the CAN frame being sent from my laptop and not getting the ACK from the Jetson.

can setup.pdf (9.4 KB)

Only some debug suggestions.

  1. Start from a low speed, like 500K. Also, you can try CAN TX/RX in Linux side first, to confirm the hardware connection is good.
  2. Can you check the CAN TX/RX waveform?
  3. Have you ever followed all instructions in CAN doc in SPE firmware package? Those settings like pinmux, SCR, should be set correctly.
  4. You can also check CAN TX first. And check whether the TX pin outputs desired waveform.



  1. Yes, I’ve tested at 500Kbps and still get the same result. The Linux side is working.
  2. I’ve checked the waveform with a scope, the photo is attached in my original post.
  3. Yes, I followed all of the steps correctly and have tried it multiple times.
  4. As mentioned in the post, I have CAN TX working,

Then can you try to inter-connect CAN0 and CAN1 (through transceiver) in TX2 and check whether CAN0 can receive the package sending from CAN1?
That may clear the clock issue, if both of them are set with same configuration.



I am still unable to see any messages received on CAN0.

I think it’s better to follow the CAN guide in SPE package exactly first, to make sure everything works as expected, without any change in source code.
In the guide, CAN0 and CAN1 are inter-connected, and will act as transmitter and receiver respectively.
The error you met means the protocol error in data or arbitration phase. (PED or PEA.) Several possible reason for this kind of error, like bad transceiver, wrong pinmux setting, bad clock, etc.