I opened relevant imx8mm-verdin.dtsi to comment regarding can@ settings interrupt-parent, interrupts and pinctrl-0.
Which pin actually you connected to MCP251x INT? pinctrl_can2_int in above mentioned dtsi is MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7. GPIO interrupt-parent should match that and you should have &gpio1 there. Interrupts setting should as well match GPIO1 IO line, which is 7 and not 14. IRQ type for MCP251x should be level sensitive, not edge. I have GPIO_ACTIVE_LOW, which evaluates to the same number as IRQ_TYPE_EDGE_FALLING Linux include’s, though clearly it should be level sensitive, not edge. In many examples where interrupt parent is GPIO I see GPIO_xxx in interrupts, not IRQ_XXX. Well, endless learning, yet another thing to figure.
I used pinctrl_gpio4 (MX8MM_IOMUXC_UART3_TXD_GPIO5_IO27).
can2 and can1 node in imx8mm-verdin-v1.1.dtsi are both edge sensitive I decided to follow that. I noticed that it is more reliable when using IRQ_TYPE_LEVEL_LOW,
Yeah, looks like I followed bad example, it should be IRQ_TYPE_LEVEL_LOW, not GPIO_ACTIVE_LOW. I wonder how did it work at all, but I didn’t loose single message in my heavy load tests, just quite high CPU load, which I thought is OK for VF61. I’ll check what happens with right setting. It may explain why Marc Kleine-Budde driver didn’t work for me.
Hi @andrecurvello.tx ,
we are using the module with a 20MHz clock as it can be configured with a jumper between 40 and 20MHz. Therefore the 20MHz setting should be fine.
@andrecurvello.tx you are right, jumper on my CAN controller is set to 40MHz.
I added this to root node:
clk40m: oscillator-1 {
compatible = “fixed-clock”; #clock-cells = <0>;
clock-frequency = <40000000>;
};
And changed can3clocks property to clk40m. But I still get:
mcp25xxfd spi1.0 can1: CAN Bus error experienced
Do you think that maybe the problem is with INT pin configuration (interrupt pin on MCP) ? Is there a way to check if interrupt on gpio5_27 is generated in linux?
Since you don’t get CRC error from driver - SPI comms are OK. Bus OFF is the sign that you have no proper wiring to your CAN communication partners, or they are operating at different bit rates.
Proper interrupt will be required to receive messages, you can send message without it.
Since you have the scope attached, disconnect your device from CAN bus, try sending some message via MCP2517 and take waveform. Find the minimum time gap between two adjacent edges. 1/dt will tell you arbitration bitrate your MCP2517 operates at. Something like that could be used to determine data bit rate, but you need to first establish proper connection at arbitration rate.
BTW how did you connect click board to CAN bus? Just CAN-L and CAN-H or indeed GND as well? GND is required.
@andrecurvello.tx@Edward@Ralph I finally implemented exetrnal CAN. Thanks for your help.
This is my wiring (from up above) that I used:
And here is my modified .dts, @andrecurvello.tx I will eventualy convert this to overlay as you already mentioned, @Edward I left edge trigger for now:
Still some words to add. I don’t want to disturb you further, just try paying attention when you have time:
There’s not small difference between IRQ_TYPE_EDGE_FALLING and IRQ_TYPE_LEVEL_LOW. I think driver should match MCP251xFD interrupt output type, which is active low.
spi-max-frequency may be too low for busier bus, as well lower SPI clock means longer delay from event on CAN bus Top allowed MCP2518FD SPI clock is 20MHz, not 2.
As I understand, since there up to 2 identical MCP251x’s on Verdin, Toradex DT uses GPIO for chip select. ECSPI is limited to one CS, so emulating 2 CS’s using GPIO’s is way to go without utilizing 2nd ECPI. Unless there are problems in ECSPI driver, automatic HW chip select should be used when single SPI slave is connected to one ECSPI. According to RM automatic CS is good up to 4096 bits long SPI messages, which is more than enough for MCP251xFD. If you are interested, cs-gpios in DT tells driver to toggle specific GPIOs instead of using automatic CS. As well have a look at IOMUX:
I ran into the CAN bus errors due to missing nodes on the network.
I thought a termination on the wire should be enough for proper transmission, but it is not. It also works for me now. Thanks a lot for your support!
Another thing that I found out is that the SPI communication does not work with the SPI hardware chip-select signal MX8MM_IOMUXC_ECSPI2_SS0_ECSPI2_SS0. If I try to use this, I get CRC single/double bit errors in the SPI communication.
Instead, I need to use the GPIO based chip-select that works fine for me now.
Do you know the reason for that issue?
I also have other SPI slaves in use and they work fine with the hardware chip-selects on the same IMX8…
Please don’t mix CRC with ECC. CRC is checksum calculation to verify data sent/received over SPI to MCP2517/18. It can’t have single or double bit errors, only OK or KO. Some MCP25xx commands include CRC sending to master or expect CRC to be added while receiving data from master. And ECC is internal MCP2517/18 RAM contents protection.
Hardware CS works well for me on VF61/VF50, but DSPI is there, not ECSPI. For some reason hardware CS on iMX6ULL and iMX7D leads to MCP2518 ECC errors. Looks like initial fill-all-MCP2518-data-RAM procedure fails, which is used to initialize RAM ECC bits. Driver initializes ECC bits by filling all the RAM. 256 bytes of dummy bytes, then next 256 bytes, etc until all RAM is written. Reducing SPI clock rate didn’t help. But it helped to disable ECSPI DMA!
If I initialize ECC RAM using non HW-CS or DMA=off DT, and not power cycle MCP2518FD, then HW-CS + DMA seem working.. until the big burst of TX messages, which makes driver reporting TEF errors…