Hard fault in spi_nrfx_spim.c>configure when writing to a SPIM interface without a CLK defined

Test platform: nRF54L15-DK
NRF Connect 2.9.0
When calling spi_write_dt, under the hood spi_nrfx_spim.c > configure is called to prepare the SPIM interface for a transmission.
The following line in spi_nrfx_spim.c > configure produces a hard fault:
	nrfy_gpio_pin_write(nrfy_spim_sck_pin_get(dev_config->spim.p_reg),
			    spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0);
nrfy_spim_sck_pin_get queries the harware SPIM device for the CLK pin.
If no CLK pin is configured, UINT_MAX is returned.
nrfy_gpio_pin_write sets the pin to the correct level for the pending transmission.
However, if no CLK pin is configured, nrfy_pio_pin_write will try to set pin 4294967295, which results in a fault.
Solution: Check if the CLK pin is valid before setting it.
    uint32_t sck_pin = nrfy_spim_sck_pin_get(dev_config->spim.p_reg);
	if (sck_pin != UINT_MAX) {
		nrfy_gpio_pin_write(sck_pin,
				    spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0);
	}
Background:
The WS2812 LED driver uses the SPI interface for a 1 wire serial interface.
To use this 1-wire interface, only MOSI is required, the CLK pin can be left unconnected.
Parents
  • As an aside, apart from the bug here, my findings were that if no physical pin was defined for the SPIM CLK pin the hardware (ie not the driver) SPIM simply didn't work at all, as it appears to use the CLK pin as the SPIM clock, not the internal 16MHz source for CLK. This is not unreasonable, given that SPIS mode uses the SCK pin. So even if the CLK pin is unused for SPIM, it must be still defined and active. Any updates on this would be appreciated.

  • I just realized that in register PSEL.SCN bit 31 indicates if the CLK pin is disconnected.

    From the NRF54L15 datasheet:

    so the patch should actually be slightly modified:

    	uint32_t sck_pin = nrfy_spim_sck_pin_get(dev_config->spim.p_reg);
    	bool sck_pin_disconnected = sck_pin & 0x80000000;
    	if (!sck_pin_disconnected) {
    		nrfy_gpio_pin_write(sck_pin,
    				    spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0);
    	}

Reply
  • I just realized that in register PSEL.SCN bit 31 indicates if the CLK pin is disconnected.

    From the NRF54L15 datasheet:

    so the patch should actually be slightly modified:

    	uint32_t sck_pin = nrfy_spim_sck_pin_get(dev_config->spim.p_reg);
    	bool sck_pin_disconnected = sck_pin & 0x80000000;
    	if (!sck_pin_disconnected) {
    		nrfy_gpio_pin_write(sck_pin,
    				    spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0);
    	}

Children
No Data
Related