configure overlay with two mcp2515 spi device but error in compiler.

hello to all,

I need to insert two CAN ports on the spi3 port of the nrf52840 with two different chip select and interrupt.

I have created an overlay file that defines two MCP2515 nodes.

overlay:

&spi3 {
    status = "okay";
    cs-gpios = <&gpio1 3 1>, <&gpio1 4 1>;
    canprimary: mcp2515@0 {
        compatible = "microchip,mcp2515";
        spi-max-frequency = <1000000>;
        int-gpios = <&gpio1 5 1>;
        status = "okay";
        label = "MCP2515_A";
        reg = <0x0>;
        osc-freq = <10000000>;
        bus-speed = <250000>;
        sjw = <1>;
        prop-seg = <2>;
        phase-seg1 = <7>;
        phase-seg2 = <6>;
        #address-cells = <1>;
        #size-cells = <0>;
		sample-point = < 875 >;
    };
	cansecondary: mcp2515@1 {
        compatible = "microchip,mcp2515";
        spi-max-frequency = <1000000>;
        int-gpios = <&gpio1 6 1>;
        status = "okay";
        label = "MCP2515_B";
        reg = <0x1>;
        osc-freq = <10000000>;
        bus-speed = <250000>;
        sjw = <1>;
        prop-seg = <2>;
        phase-seg1 = <7>;
        phase-seg2 = <6>;
        #address-cells = <1>;
        #size-cells = <0>;
		sample-point = < 875 >;
    };
};

if I compile with only one of the two chips, I have no problems with initialization:

definition:

#define CAN0_NODE DT_NODELABEL(canprimary)
#define CAN1_NODE DT_NODELABEL(cansecondary)

initialization:

void can_api_init(void)
{
    int ret;
    can_dev_0 = DEVICE_DT_GET(CAN0_NODE);
    printk("GET: %s\n", can_dev_0->name); // node 1

/*     can_dev_1 = DEVICE_DT_GET(CAN1_NODE);
    printk("GET: %s\n", can_dev_1->name); */ // node 2
    
    ... etc

if I activate the second node,

void can_api_init(void)
{
    int ret;
    can_dev_0 = DEVICE_DT_GET(CAN0_NODE);
    printk("GET: %s\n", can_dev_0->name);

    can_dev_1 = DEVICE_DT_GET(CAN1_NODE); // <= activate second node !!!
    printk("GET: %s\n", can_dev_1->name); 

the compiler gives me an error:

[198/198] Linking C executable zephyr/zephyr.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       58916 B         1 MB      5.62%
            SRAM:       31880 B       256 KB     12.16%
        IDT_LIST:          0 GB         2 KB      0.00%
 *  Terminal will be reused by tasks, press any key to close it. 

 *  Executing task: nRF Connect: Build: dual_can_external/build_external (active) 

Building dual_can_external
west build --build-dir /opt/nordic/CAN_52840dk/dual_can_external/build_external /opt/nordic/CAN_52840dk/dual_can_external

[1/11] Building C object CMakeFiles/app.dir/src/can/can.c.obj
[2/11] Linking C static library app/libapp.a
[3/11] Linking C executable zephyr/zephyr_pre0.elf
FAILED: zephyr/zephyr_pre0.elf zephyr/zephyr_pre0.map 
: && ccache /opt/nordic/ncs/toolchains/v2.0.0/opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc   zephyr/CMakeFiles/zephyr_pre0.dir/misc/empty_file.c.obj -o zephyr/zephyr_pre0.elf  -fuse-ld=bfd  -Wl,-T  zephyr/linker_zephyr_pre0.cmd  -Wl,-Map=/opt/nordic/CAN_52840dk/dual_can_external/build_external/zephyr/zephyr_pre0.map  -Wl,--whole-archive  app/libapp.a  zephyr/libzephyr.a  zephyr/arch/common/libarch__common.a  zephyr/arch/arch/arm/core/aarch32/libarch__arm__core__aarch32.a  zephyr/arch/arch/arm/core/aarch32/cortex_m/libarch__arm__core__aarch32__cortex_m.a  zephyr/arch/arch/arm/core/aarch32/mpu/libarch__arm__core__aarch32__mpu.a  zephyr/lib/libc/minimal/liblib__libc__minimal.a  zephyr/lib/posix/liblib__posix.a  zephyr/soc/arm/common/cortex_m/libsoc__arm__common__cortex_m.a  zephyr/soc/arm/nordic_nrf/nrf52/libsoc__arm__nordic_nrf__nrf52.a  zephyr/drivers/clock_control/libdrivers__clock_control.a  zephyr/drivers/console/libdrivers__console.a  zephyr/drivers/gpio/libdrivers__gpio.a  zephyr/drivers/spi/libdrivers__spi.a  zephyr/drivers/can/libdrivers__can.a  zephyr/drivers/serial/libdrivers__serial.a  zephyr/drivers/timer/libdrivers__timer.a  zephyr/drivers/pinctrl/libdrivers__pinctrl.a  modules/nrf/lib/fatal_error/lib..__nrf__lib__fatal_error.a  modules/nrf/drivers/hw_cc310/lib..__nrf__drivers__hw_cc310.a  modules/hal_nordic/nrfx/libmodules__hal_nordic__nrfx.a  modules/segger/libmodules__segger.a  -Wl,--no-whole-archive  zephyr/kernel/libkernel.a  zephyr/CMakeFiles/offsets.dir/./arch/arm/core/offsets/offsets.c.obj  -L"/opt/nordic/ncs/toolchains/v2.0.0/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/10.3.0/thumb/v7e-m/nofp"  -L/opt/nordic/CAN_52840dk/dual_can_external/build_external/zephyr  -lgcc  zephyr/arch/common/libisr_tables.a  -no-pie  -mcpu=cortex-m4  -mthumb  -mabi=aapcs  -mfp16-format=ieee  -Wl,--gc-sections  -Wl,--build-id=none  -Wl,--sort-common=descending  -Wl,--sort-section=alignment  -Wl,-u,_OffsetAbsSyms  -Wl,-u,_ConfigAbsSyms  -nostdlib  -static  -Wl,-X  -Wl,-N  -Wl,--orphan-handling=warn  /opt/nordic/ncs/v2.0.0/nrfxlib/crypto/nrf_cc310_platform/lib/cortex-m4/soft-float/no-interrupts/libnrf_cc310_platform_0.9.14.a && cd /opt/nordic/CAN_52840dk/dual_can_external/build_external/zephyr && /opt/nordic/ncs/toolchains/v2.0.0/Cellar/cmake/3.20.5/bin/cmake -E echo
/opt/nordic/ncs/toolchains/v2.0.0/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/10.3.0/../../../../arm-zephyr-eabi/bin/ld.bfd: app/libapp.a(can.c.obj): in function `can_api_init':
/opt/nordic/CAN_52840dk/dual_can_external/src/can/can.c:401: undefined reference to `__device_dts_ord_130'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: /opt/nordic/ncs/toolchains/v2.0.0/bin/cmake --build /opt/nordic/CAN_52840dk/dual_can_external/build_external

some idea ??
Thank you

Parents Reply Children
  • Try the following patch:

    diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c
    index 395492ea77..b8fe42e4ef 100644
    --- a/drivers/can/can_mcp2515.c
    +++ b/drivers/can/can_mcp2515.c
    @@ -967,35 +967,38 @@ static int mcp2515_init(const struct device *dev)
     	return ret;
     }
     
    -#if DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay)
    -
    -static K_KERNEL_STACK_DEFINE(mcp2515_int_thread_stack,
    -			     CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE);
    -
    -static struct mcp2515_data mcp2515_data_1 = {
    -	.int_thread_stack = mcp2515_int_thread_stack,
    -	.tx_busy_map = 0U,
    -	.filter_usage = 0U,
    -};
    -
    -static const struct mcp2515_config mcp2515_config_1 = {
    -	.bus = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8), 0),
    -	.int_gpio = GPIO_DT_SPEC_INST_GET(0, int_gpios),
    -	.int_thread_stack_size = CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE,
    -	.int_thread_priority = CONFIG_CAN_MCP2515_INT_THREAD_PRIO,
    -	.tq_sjw = DT_INST_PROP(0, sjw),
    -	.tq_prop = DT_INST_PROP_OR(0, prop_seg, 0),
    -	.tq_bs1 = DT_INST_PROP_OR(0, phase_seg1, 0),
    -	.tq_bs2 = DT_INST_PROP_OR(0, phase_seg2, 0),
    -	.bus_speed = DT_INST_PROP(0, bus_speed),
    -	.osc_freq = DT_INST_PROP(0, osc_freq),
    -	.sample_point = DT_INST_PROP_OR(0, sample_point, 0),
    -	.phy = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(0, phys)),
    -	.max_bitrate = DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(0, 1000000),
    -};
    -
    -DEVICE_DT_INST_DEFINE(0, &mcp2515_init, NULL,
    -		    &mcp2515_data_1, &mcp2515_config_1, POST_KERNEL,
    -		    CONFIG_CAN_INIT_PRIORITY, &can_api_funcs);
    -
    -#endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay) */
    +#define MCP2515_DEFINE(inst)  \
    +\
    +static K_KERNEL_STACK_DEFINE(mcp2515_int_thread_stack,\
    +			     CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE);\
    +\
    +static struct mcp2515_data mcp2515_data_##inst = {\
    +	.int_thread_stack = mcp2515_int_thread_stack,\
    +	.tx_busy_map = 0U,\
    +	.filter_usage = 0U,\
    +};\
    +\
    +                        \
    +                              \
    +	static const struct mcp2515_config mcp2515_config_##inst = {   \
    +		.bus = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0), \
    +		.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),\
    +		.int_thread_stack_size = CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE,\
    +		.int_thread_priority = CONFIG_CAN_MCP2515_INT_THREAD_PRIO,\
    +		.tq_sjw = DT_INST_PROP(inst, sjw),\
    +		.tq_prop = DT_INST_PROP_OR(inst, prop_seg, 0),\
    +		.tq_bs1 = DT_INST_PROP_OR(inst, phase_seg1, 0),\
    +		.tq_bs2 = DT_INST_PROP_OR(inst, phase_seg2, 0),\
    +		.bus_speed = DT_INST_PROP(inst, bus_speed),\
    +		.osc_freq = DT_INST_PROP(inst, osc_freq),\
    +		.sample_point = DT_INST_PROP_OR(inst, sample_point, 0),\
    +		.phy = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, phys)),\
    +		.max_bitrate = DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(inst, 1000000),\
    +	};\
    +\
    +	DEVICE_DT_INST_DEFINE(inst, &mcp2515_init, NULL,\
    +				&mcp2515_data_##inst, &mcp2515_config_##inst, POST_KERNEL,\
    +				CONFIG_CAN_INIT_PRIORITY, &can_api_funcs);\
    +
    +
    +DT_INST_FOREACH_STATUS_OKAY(MCP2515_DEFINE)
    

    or just remove this code, and replace it with the following:

    #define MCP2515_DEFINE(inst)  \
    \
    static K_KERNEL_STACK_DEFINE(mcp2515_int_thread_stack,\
    			     CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE);\
    \
    static struct mcp2515_data mcp2515_data_##inst = {\
    	.int_thread_stack = mcp2515_int_thread_stack,\
    	.tx_busy_map = 0U,\
    	.filter_usage = 0U,\
    };\
    \
                            \
                                  \
    	static const struct mcp2515_config mcp2515_config_##inst = {   \
    		.bus = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0), \
    		.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),\
    		.int_thread_stack_size = CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE,\
    		.int_thread_priority = CONFIG_CAN_MCP2515_INT_THREAD_PRIO,\
    		.tq_sjw = DT_INST_PROP(inst, sjw),\
    		.tq_prop = DT_INST_PROP_OR(inst, prop_seg, 0),\
    		.tq_bs1 = DT_INST_PROP_OR(inst, phase_seg1, 0),\
    		.tq_bs2 = DT_INST_PROP_OR(inst, phase_seg2, 0),\
    		.bus_speed = DT_INST_PROP(inst, bus_speed),\
    		.osc_freq = DT_INST_PROP(inst, osc_freq),\
    		.sample_point = DT_INST_PROP_OR(inst, sample_point, 0),\
    		.phy = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, phys)),\
    		.max_bitrate = DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(inst, 1000000),\
    	};\
    \
    	DEVICE_DT_INST_DEFINE(inst, &mcp2515_init, NULL,\
    				&mcp2515_data_##inst, &mcp2515_config_##inst, POST_KERNEL,\
    				CONFIG_CAN_INIT_PRIORITY, &can_api_funcs);\
    
    
    DT_INST_FOREACH_STATUS_OKAY(MCP2515_DEFINE)

    I have not tested it thoroughly, so let me know if you face any issues.

    Best regards,

    Simon

  • ok, Simon
    tomorrow morning I try to do it and I tell you.
    thank you

    Best Regards,

    Silvio

  • Hi,

    SDK versions since 2.1.x have updated drivers that now support multiple instances of the MCP2515

    problem solved.

    Best Regards

    babos

Related