Skip to content

Add CAN to AMDC#459

Draft
mohamed-dek1 wants to merge 6 commits intov1.4.xfrom
user/moha2063/can-firmware
Draft

Add CAN to AMDC#459
mohamed-dek1 wants to merge 6 commits intov1.4.xfrom
user/moha2063/can-firmware

Conversation

@mohamed-dek1
Copy link
Copy Markdown

In progress

@mohamed-dek1
Copy link
Copy Markdown
Author

05/07/2025

AMDC CAN Spring 2025 End of Semester Report

The purpose of this report is to describe the work done on getting CAN on the AMDC.

Overview

This project started with the goal of having the AMDC communicate with a 3rd party component, specifically the BorgWarner HVLP-20 motor drive, over a CAN bus. There had been an attempt at something similar years ago, you can find more information on that here:

A couple of sub-goals for this project were to have a successful loop-back and AMDC to AMDC CAN communication.

Loop-back

We were able to achieve a successful loop-back and observed that the signal from the transceiver of CANA was the same as the receiver of CANB. This was done by probing the single-ended pins on the differential transceiver of each side.

Logic Analyzer capture of signal

can-loopback-salaea

Diagram of connections

can-loopback-cables

One issue with this test was that the CAN signal appears to reach the second tranceiver on the CAN board and the peripheral in the Zynq-7000 SoC, but can't be printed through the driver. This could be an issue with the driver, as the can_rcv function reports that the RxFIFO buffer is always empty. This could also be an issue with the Vivado setup. Both hypotheses are described in more detail below.

For more details, please see the following issue:

AMDC to AMDC

We were able to achieve a conditional AMDC (A) to AMDC (B) CAN communication and observed that the signal from the transceiver of CAN0A was the same as the receiver of CAN0B. This was done by probing the single-ended pins on the differential transceiver of each board.

Logic Analyzer capture of signal

can-amdc-amdc-salaea

Diagram of connections

can-amdc-amdc-cables

Similar to the loop-back test, the CAN signal can't be printed even after successfully reaching the Zynq. In the image above, CAN0A is connected to CAN1A, essentially doing a loopback, then it's connected to CAN0B through the terminal blocks on the side of the board. Under these conditions, we are able to achieve AMDC to AMDC CAN communication

For more details, please see the following issue:

Hardware

There are currently 2 assembled CAN boards, and they're both on the CAN Board Log. They've been tested and work in the conditional fashion as described above.

Although both boards are functional, there are changes that could make them easier to debug and work with. Some of those changes include:

  • Test points to make probing the signal easier.
  • LEDs to indicate if the board is powered.
  • Updating the silkscreen to properly label the CANH terminal on the CANA side.
can-silkscreen

It would also be nice to have a male-to-male DB9 cable for when 2 CAN boards need to be connected to each other.

Vivado Changes

The CAN signal is routed from the GPIO port through the gp3io_mux and finally to the CAN peripheral in the Zynq. Because there are only 2 peripherals in the Zynq, there can only be one CAN board connected to the AMDC at a time. Currently, the peripherals are hard-wired1 to GPIO port 4 on device 5. This can be improved on by creating another MUX to select which GPIO port you want to use through the driver.

During the loop-back test, we observed that the signal had been inverted over the transmission. After confirming this issue, we created a new NOT IP block that was placed before the Zynq CAN RX inputs.

CAN signal before creating the NOT IP block

can-before-not

NOT IP block location

can-not-ip

You might notice that the NOT block is only on the CAN0_RX; this is because the screenshot was taken during an experiment to see whether that was the cause of the CANB side of the board not "receiving" a signal. It was later found that neither side could print out the CAN signal.

For more details, please see the following issue:

Driver

In the current state of the driver, you are able to initialize 2 XCanPs peripherals, CanPs0 and CanPs1. Most functions will take in a can_peripheral_t argument, which will correspond to the CAN peripheral to target. After figuring out which peripheral you are targeting, each function will use some of the many XCanPs_XXX functions that are within the xcanps files. These files are generated by the bsp based on your Vivado setup, which in our case includes the 2 CAN peripherals in the Zynq. There are functions to send, receive, change mode, change baud rate, set btr, and some helpful print functions.

As noted above, there is an issue where the CAN signal cannot be printed even though it is reaching the CAN peripheral within the Zynq. This could be due to an improper configuration of the peripheral in the driver. It could also be that we aren't reading the buffer in time to get the packet.

Regardless, the xcanps file needs to be researched further to figure out how to properly use it. For a functional CAN board, the driver needs to be able to send, receive, and display packets for both peripherals at the same time.

CAN APP

When you program the AMDC with the CAN APP, it will initialize both CAN peripherals to run at the same time. Most commands will require you to specify which peripheral you want to talk to. Every command and a brief description of each can be found below.

CAN Commands

init
"Start task"
deinit
"Stop task"
selftest
"Run test message in loopback mode"
send <number of bytes>
"Send a predefined message with specified number of bytes"
print
"Prints latest message"
print mode
"Prints mode of CAN peripheral"
print peripheral
"Prints current CAN peripheral in use"
setmode <mode>
"Set CAN mode {loopback, sleep, config, normal}"
setbaud <baudrate>
"Set CAN baudrate (type 0 for default)"
set btr <jump> <first time> <second time>
"Set CAN bit timing register (type 0s for default)"
peripheral <device_id>
"Set CAN peripheral in use: either 0 or 1"

Future Work

The immediate plan is to get around the wiring as shown above in the AMDC to AMDC communication. The proper wiring should be from AMDC A --> CAN(0 or 1)A --> CAN(0 or 1)B --> AMDCB. The next immediate issue would be to figure out how to properly receive a packet. After getting these two issues resolved, the CAN board should be able to perform a proper AMDC-to-AMDC CAN communication. This will also allow us to push this version of the CAN interface to the develop branch to prepare for a release.

The following issues can be worked on in the future:

  • A separate mux to choose which GPIO port to connect the CAN peripheral to.

Footnotes

  1. On the Vivado diagram, the input of GPIO4 is "wired" into the respective rx pins of the CAN peripherals

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant