The Forlinx OKMX8MP-C development board is equipped with two native CAN buses. However, in certain product development scenarios, there is a need for additional CAN buses. This article will introduce a method for SPI to CAN conversion, providing engineers with a reference.
• The FETMX8MP-C SoM has two native SPI buses. Currently, the pins of SPI1 are being used for LED and UART3 functions, while SPI2 is configured as a normal SPI2 interface. Taking SPI2 to CAN conversion as an example, the process involves porting the SPI to CAN chip;
• The model of the SPI to CAN chip is MCP2518. This chip is capable of converting to CAN-FD. If only CAN functionality is required, you can refer to this method for porting MCP2515 or other chips;
• The driver for the MCP2518 chip in this porting process is sourced from the i.MX8MQ's firmware code. The MCP2518 chip is already ported by default in the processor.
Create a folder named "mcp25xxfd" under the path "OK8MP-linux-kernel/drivers/net/can/spi/". Place the relevant files (including .c files, .h files, Makefile, Kconfig, etc.) in this folder.
vi OK8MQ-linux-kernel/include/linux/can/rx-offload.h
Add:
int can_rx_offload_add_manual(struct net_device *dev,
struct can_rx_offload *offload,
unsigned int weight)
vi OK8MQ-linux-kernel/drivers/net/can/rx-offload.c
Add:
int can_rx_offload_add_manual(struct net_device *dev,
struct can_rx_offload *offload,
unsigned int weight)
{
if (offload->mailbox_read)
return -EINVAL;
return can_rx_offload_init_queue(dev, offload, weight);
}
EXPORT_SYMBOL_GPL(can_rx_offload_add_manual);
vi OK8MP-linux-kernel/drivers/net/can/spi/Makefile
Add:
obj-y += mcp25xxfd/
vi OK8MP-linux-kernel/drivers/net/can/spi/Kconfig
Add:
source "drivers/net/can/spi/mcp25xxfd/Kconfig"
vi OK8MP-linux-kernel/arch/arm64/configs/OK8MP-C_defconfig
Get:CONFIG_CAN_MCP251X=y
Change to:# CONFIG_CAN_MCP251X is not set
Add:CONFIG_CAN_MCP25XXFD=y
vi OK8MP-linux-kernel/arch/arm64/boot/dts/freescale/OK8MP-C.dts
Add:
clocks{
mcp2518fd_clock:
mcp2518fd_clock{
compatible = "fixed-clock";
#clock-cells
clock-frequency
};
};
GPIOUNK1IO21 is used as an interrupt pin here.
vi OK8MP-linux-kernel/arch/arm64/boot/dts/freescale/OK8MP-C.dts
Add:
pinctrl_ecspi2_can: ecspi2can{
fsl,pins = < MX8MP_IOMUXC_SAI2_RXFS__GPIO4_IO21 0x40000 >;
};
vi OK8MP-linux-kernel/arch/arm64/boot/dts/freescale/OK8MP-C.dts
From:
&ecspi2{
#address-cells=;
#size-cells=;
fsl,spi-num-chipselects=;
pinctrl-names= "default";
pinctrl-0= <&pinctrl_ecspi2 &pinctrl_ecspi2_cs>;
cs-gpios= <&gpio5 13 GPIO_ACTIVE_LOW>;
status= "okay";
spidev1:spi@0 {
reg=;
compatible= "rohm,dh2228fv";
spi-max-frequency=;
};
};
Change to:
&ecspi2{
#address-cells=;
#size-cells=;
fsl,spi-num-chipselects=;
pinctrl-names= "default";
pinctrl-0= <&pinctrl_ecspi2 &pinctrl_ecspi2_cs &pinctrl_ecspi2_can>;
cs-gpios= <&gpio5 13 GPIO_ACTIVE_LOW>;
status= "okay";
mcp1:mcp2518fd@0{
compatible= "microchip,mcp2518fd";
reg=;
spi-max-frequency=;
clocks= <&mcp2518fd_clock2>;
interrupts-extended= <&gpio4 21 IRQ_TYPE_LEVEL_LOW>;
};
};
After completing the above modifications, you can compile and burn the OKMX8MP-C development board with the newly generated image.
Connect the MCP2518 chip to the SPI2 interface, start the OKMX8MP-C development board, and then use the ifconfig -a command to view it, and you can see that there is one more CAN node.
Originally published at www.forlinx.net.