Get CAN FD device MCP2518FD working

Hi,

I am having a hard time for days now trying to get the MCP2518FD working on a nRF9160-DK board. This device, embedding CAN transceiver and receiver, is accessible through SPI.

I ran into several forums and some doc here and there but nothing seems to match my case.

As a context, I use the ncs v2.6.0 and a custom board (which for now is basically just the nRF9160-DK board, meaning that my dts file simply includes <nordic/nrf9160ns_sica.dtsi> and defines partitions) and then I use an overlay for the real custom devices, which is as follows (shrunk to show only relevant fields) :

&pinctrl {
	uart0_default: uart0_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 29)>,
				<NRF_PSEL(UART_RTS, 0, 27)>;
		};
		group2 {
			psels = <NRF_PSEL(UART_RX, 0, 28)>,
				<NRF_PSEL(UART_CTS, 0, 26)>;
			bias-pull-up;
		};
	};

	uart0_sleep: uart0_sleep {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 29)>,
				<NRF_PSEL(UART_RX, 0, 28)>,
				<NRF_PSEL(UART_RTS, 0, 27)>,
				<NRF_PSEL(UART_CTS, 0, 26)>;
			low-power-enable;
		};
	};
	
	spi3_default: spi3_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 1)>,
			<NRF_PSEL(SPIM_MOSI, 0, 10)>,
			<NRF_PSEL(SPIM_MISO, 0, 13)>;
		};
	};

	spi3_sleep: spi3_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 1)>,
					<NRF_PSEL(SPIM_MOSI, 0, 10)>,
					<NRF_PSEL(SPIM_MISO, 0, 13)>;
			low-power-enable;
		};
	};
};


/ {
	model = "Nordic nRF9160 DK NRF9160";
	compatible = "nordic,nrf9160-dk-nrf9160";

	chosen {
		zephyr,console = &uart0;
		zephyr,shell-uart = &uart0;
		zephyr,uart-mcumgr = &uart0;
		zephyr,canbus = &mcp251xfd;
	};

	/* These aliases are provided for compatibility with samples */
	aliases {
		spi3 = &spi3;
	};
};

&spi3 {
	status = "okay";
	mcp251xfd: mcp251xfd@0 {
		compatible = "microchip,mcp251xfd";
		status = "okay";
		reg = <0x0>;
		osc-freq = <40000000>;
		int-gpios = <&gpio0 16 0>;
		spi-max-frequency = <8000000>;
		bus-speed-data = <1000000>;
		bus-speed = <125000>;
	};

	cs-gpios = <&gpio0 0 0>;
	pinctrl-0 = <&spi3_default>;
	pinctrl-names = "default", "sleep";
	pinctrl-1 = <&spi3_sleep>;
};

Which comes along with this prj.conf file (shrunk to show only relevant fields) : 

# General config
CONFIG_ASSERT=y
CONFIG_BUILD_WITH_TFM=y
CONFIG_TRUSTED_EXECUTION_NONSECURE=y

# Increase memory heap
CONFIG_HEAP_MEM_POOL_SIZE=4096
CONFIG_MAIN_STACK_SIZE=4096

CONFIG_SPI=y
CONFIG_CAN=y
CONFIG_CAN_FD_MODE=y
CONFIG_CAN_MCP251XFD=y
# CONFIG_CAN_MCP251XFD_READ_CRC_RETRIES=3

Just to let you know, my MCP2518FD is in fact the Mikrochip MCP2518FD clickboard but I expected to have it working without using the -DSHIELD compilation option since it only has to be seen as a SPI device.

Now that said, I am pretty new to the devicetree and Nordic dev environment. I got to understand that the main interface I will be using is the <zephyr/drivers/can.h>. But my problem pops before any manual usage of these functions. I managed to put some log in the "zephyr\drivers\can\can_mcp251xfd.c" in the mcp251xfd_init and mcp251xfd_read_crc functions (called by the very first mcp251xfd_set_mode_internal and mcp251xfd_reset functions). In the nRF Connect's Serial Terminal v1.3.1, here is the result I got : 

[Sec Thread] Secure image initializing!
Booting TF-M v2.0.0
mutex init
spi init done
int gpio init done
int gpio configured
int gpio callback init
int gpio callback added
thread initialized
try reset
try set mode config
try read crc
trial 1
crc_in :  34779 (0x87db)
tx_buf content before send :
0xb0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 0x0 
rx_buf content after send :
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
crc 52805 (0xce45)
trial 0
crc_in :  34779 (0x87db)
tx_buf content before send :
0xb0 0x0 0x4 0x0 0x0 0x0 0x0 0x0 0x0 
rx_buf content after send :
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
crc 52805 (0xce45)
read_crc_reg is NULL
set mode internal error code : -22
[00:00:00.371,063] <err> can_mcp251xfd: Failed to reset the device [-22]
*** Booting nRF Connect SDK v3.5.99-ncs1 ***
[00:00:00.371,246] <err> gck_tcu: Device mcp251xfd@0 is not ready

So from my understanding, the init function is implicitly called at boot time. SPI and GPIO init, inherited from what I specified in the overlay, work well. But when it comes to the very first SPI communication, I got a CRC error which I can't understand the origin since no complex operation is done here.

Moreover, I only wired the SPI and power pins. Whenever I also wire the P0.16 to the INT pin of my clickboard, I don't even get all this log and stop after "Booting TF-M v2.0.0", meaning I don't even boot I guess.

Feel free to ask for any additionnal information that might help.

Thank you in advance for your help.

Guillaume R

  • Hi Guillaume

    Have you ensured that the voltage levels are compatible between the nRF9160-DK and the MCP board? 

    By default the GPIO's on the 9160DK will run at 1.8V, and based on the specification of the MCP2518 the legal supply range for this device is 2.7-5.5V, so if the nRF9160 is running at 1.8V they will not be able to communicate.

    The SW9 switch on the nRF9160-DK will allow you to change the GPIO voltage to 3V, have you tried this? 

    Best regards
    Torbjørn

  • Indeed, and as a first try I used the switch SW9 on the nRF9160-DK to get a 3V on the GPIOs, but I wasn't sure it was enough. So now I am using a 5V pin available on the board to power the MCP clickboard (for the record my MCP is in fact the MikroE clickboard on which I set the hardware switch to 5V too, and using this clickboard I also have test points that I used for voltage monitoring and a power led which is on), and switched back the DK GPIOs to 1.8V

  • Hi Guillaume

    You mean to say the pins on the MikroE clickboard are running at 5V while the DK GPIO's are running at 1.8V? 

    That certainly won't work. 

    Is there some way to run the MikroE board using a 3V supply rather than 5V?

    Best regards
    Torbjørn

  • Hi,

    thank you very much for your advice. There was probably a problem here, so as you suggested I powered the MCP clickboard with both 5V and 3V (using the SW9 on position 3V) because the MCP needs both (5V being only used for the CAN bus if my understanding was correct).

    There was also another problem in my config which I figured out monitoring the SPI signals : using MCP2518FD and nRF9160DK, the CS must be configured as active low (which I did not notice from the microchip,mcp251xfd's yaml example). Both the power wiring and the proper CS config got me to communicate with the device.

    And just to let other people know if they use the same devices, the general CAN interface available in zephyr (can.h) seems to allow loopback. It does, but only external loopback. But the click board and the MCP itself allow internal loopback for testing purpose, which is very convenient. In order to switch to this mode, I had to edit the zephyr can_mcp251xfd.c MCP's driver in the mcp251xfd_set_mode function and use the constant MCP251XFD_REG_CON_MODE_INT_LOOPBACK instead of MCP251XFD_REG_CON_MODE_EXT_LOOPBACK.

    From now on I have been able to get the MCP2518FD clickboard working. I am still facing some issues in this internal loopback mode, works fine at the beginning but at some point I lose transmission (and thus reception). I dug until mailbox usage, their flags and semaphores but was unable to determine the root cause, but that will be the object of another ticket if needed.

    Anyway, thank you so much for your help,

    Best regards,

    Guillaume

  • Hi Guillaume

    Glad I could be of help, and good to hear that you were able to get some progress. I will close this ticket then Slight smile

    Best regards
    Torbjørn

Related