Switch between SPIM and SPIS at run-time

I know this is not a typical application, but I need to switch between SPIM and SPIS at runtime for using SPI in a M-LVDS scenario.  I'm pretty sure that the Zephyr level drivers are out so I moved to the nrfx level and I managed to get most issues straightened out.  However, I get this error: 

C:\ncs\v2.4.1\zephyr\drivers\spi\spi_nrfx_spis.c:305: multiple definition of `__device_dts_ord_114'; zephyr/drivers/spi/libdrivers__spi.a(spi_nrfx_spim.c.obj):C:\ncs\v2.4.1\zephyr\drivers\spi\spi_nrfx_spim.c:625: first defined here

Here is my config:

CONFIG_SPI=y
CONFIG_SPI_SLAVE=y
CONFIG_SPI_NRFX=y
CONFIG_NRFX_SPIS0=y
CONFIG_NRFX_SPIM0=y
CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=512

And my overlay (cs is a custom vendor):

&spi0 {
	compatible = "nordic,nrf-spis", "nordic,nrf-spim";
	status = "okay";
	cs-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
	clock-frequency = <8000000>;
	def-char = <0x00>;

	reg_spi_slave: reg_spi_slave@0 {
		compatible = "cs,spi-device";
		status = "okay";
		spi-max-frequency = <8000000>;
		frame-format = <0>;
		duplex = <0>;
		reg = <0>;
	};	
};

Here is a preliminary snippet of how I plan on switching from master to slave:

static void switch_to_master(void)
{
    int err = 0;
    //spi_release_dt(current_spi_dev);
    nrfx_spis_uninit(&spis_inst);
    //current_spi_dev = &spi_spec_master;
    nrfx_timer_disable(&timer_instance);
    gpio_pin_set_dt(&master_spi_enable, MASTER_ENABLE);
    nrfx_spim_config_t spim_config = NRFX_SPIM_DEFAULT_CONFIG(SCK_PIN,
                                                              MOSI_PIN,
                                                              MISO_PIN,
                                                              SS_PIN);

    err = nrfx_spim_init(&spim_inst, &spim_config, spim_handler, NULL);
	if (err)
	{
        LOG_ERR("Failed to initialize SPIM (err %d)", err);
		return;
    }

    IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_SPIM_INST_GET(SPI_INSTANCE)), IRQ_PRIO_LOWEST,
                       NRFX_SPIM_INST_HANDLER_GET(SPI_INSTANCE), 0);
}

static void switch_to_slave(void)
{
    int err = 0;
    //spi_release_dt(current_spi_dev);
    nrfx_spim_uninit(&spim_inst);
    //current_spi_dev = &spi_spec_slave;
    nrfx_timer_disable(&timer_instance);
    nrfx_spis_config_t spis_config = NRFX_SPIS_DEFAULT_CONFIG(SCK_PIN,
                                                              MOSI_PIN,
                                                              MISO_PIN,
                                                              SS_PIN);

    err = nrfx_spis_init(&spis_inst, &spis_config, spis_handler, &spis_inst);
	if (err)
	{
        LOG_ERR("Failed to initialize SPIM (err %d)", err);
		return;
    }

    IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_SPIS_INST_GET(SPI_INSTANCE)), IRQ_PRIO_LOWEST,
                       NRFX_SPIS_INST_HANDLER_GET(SPI_INSTANCE), 0);

    gpio_pin_set_dt(&master_spi_enable, SLAVE_ENABLE);
}

The `gpio_pin_set_dt(&master_spi_enable, MASTER_ENABLE);` code switches my transceiver direction.  I'm assuming both the nrfx SPIM and SPIS are causing a collision with generated device tree macros.  Can anyone give me some suggestions?  I may have to go down to the hal level, but I hope not.

Parents Reply Children
No Data
Related