SPI Peripheral Causes Unexpected Voltage on 1.8V_SYS When Interfacing nRF52840 with LSM6DSV16

I am experiencing an issue with my board, where I have interfaced an nRF52840 with an LSM6DSV16 via SPI.

The nRF52840 chip, once started, can decide whether or not to power the LSM6DSV16 (1.8V_SYS in the schematic above) through a signal controlling an LDO. However, I noticed that if I configure SPI in the DTS file by enabling it with status="okay";

&spi0 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi0_default>;
	pinctrl-1 = <&spi0_sleep>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
	
	lsm6dsv16x: lsm6dsv16x@0 {
		compatible = "st,lsm6dsv16x";		
        reg = <0>;
        spi-max-frequency = <8000000>;
    };
};

spi0_default: spi0_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 4)>,
				<NRF_PSEL(SPIM_MOSI, 0, 28)>,
				<NRF_PSEL(SPIM_MISO, 0, 29)>;
		};
	};

	spi0_sleep: spi0_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 4)>,
				<NRF_PSEL(SPIM_MOSI, 0, 28)>,
				<NRF_PSEL(SPIM_MISO, 0, 29)>;
			low-power-enable;
		};
	};

even if I disable the LDO powering the LSM6DSV16, I still have a (return?) voltage on 1.8V_SYS, which is approximately 1.5V/1.7V. If I disable SPI with status="disabled";

&spi0 {
	compatible = "nordic,nrf-spim";
	status = "disabled";
	pinctrl-0 = <&spi0_default>;
	pinctrl-1 = <&spi0_sleep>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
	
	lsm6dsv16x: lsm6dsv16x@0 {
		compatible = "st,lsm6dsv16x";		
        reg = <0>;
        spi-max-frequency = <8000000>;
    };
};

spi0_default: spi0_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 4)>,
				<NRF_PSEL(SPIM_MOSI, 0, 28)>,
				<NRF_PSEL(SPIM_MISO, 0, 29)>;
		};
	};

	spi0_sleep: spi0_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 4)>,
				<NRF_PSEL(SPIM_MOSI, 0, 28)>,
				<NRF_PSEL(SPIM_MISO, 0, 29)>;
			low-power-enable;
		};
	};

the issue does not occur, and everything works as expected. At this point, I believe the problem is due to the SPI signal handling by the nRF52840, which somehow passes through the LSM6DSV16 (internal pull-up resistors?).

So, I ask: why am I seeing this behavior, and how can I fix it? Is there a way to modify the peripheral's status at runtime?

Parents
  • Hi there,

    What GPIO are you using to control the LDO? Do you measure any difference in the GPIO signal when you enable the SPI node versus when it's disabled?

    Have you tried disconnecting the CS pin from the LSM6DSV16, maybe it's backpowering it through that. 

    regards

    Jared 

  • What GPIO are you using to control the LDO?

    The GPIO controlling the LDO is:

    pwr_en_mcu: gpiocustom_0 {
    			gpios = < &gpio1 8 GPIO_ACTIVE_HIGH >;
    			label = "PWR_EN_MCU";
    		};

    Do you measure any difference in the GPIO signal when you enable the SPI node versus when it's disabled?

    I don’t have the possibility to check the signals on the board since I don’t have access to them.

    Have you tried disconnecting the CS pin from the LSM6DSV16, maybe it's backpowering it through that. 

    At first, I solved the problem by reconfiguring the SPI GPIOs as inputs

    static int Disable_Imu_Spi_Gpios( void )
    {
        const struct device *gpio0Dev = DEVICE_DT_GET( DT_NODELABEL( gpio0 ) );
    
        if ( !device_is_ready( gpio0Dev ) )
        {
            Error_Managing_Signal( SYSTEM_ERROR_INIT_GPIO, __FILE__, __LINE__ );
            return -1;
        }
    
        if (
            ( gpio_pin_configure( gpio0Dev, IMU_SPI_SCK_PIN, GPIO_INPUT ) < 0 ) ||
            ( gpio_pin_configure( gpio0Dev, IMU_SPI_MOSI_PIN, GPIO_INPUT ) < 0 ) ||
            ( gpio_pin_configure( gpio0Dev, IMU_SPI_MISO_PIN, GPIO_INPUT ) < 0 ) ||
            ( gpio_pin_configure( gpio0Dev, IMU_SPI_CS_PIN, GPIO_INPUT ) < 0 )
            )
    	{
            Error_Managing_Signal( SYSTEM_ERROR_INIT_GPIO, __FILE__, __LINE__ );
    		return -1;
    	}
    
        return 0;
    }

    Now, I tried following your advice: I only disabled the SPI CS, and the problem seems to have disappeared. It really seems like the issue is with the CS. This has never happened to me before. Isn’t the CS supposed to be a high-impedance pin?

Reply
  • What GPIO are you using to control the LDO?

    The GPIO controlling the LDO is:

    pwr_en_mcu: gpiocustom_0 {
    			gpios = < &gpio1 8 GPIO_ACTIVE_HIGH >;
    			label = "PWR_EN_MCU";
    		};

    Do you measure any difference in the GPIO signal when you enable the SPI node versus when it's disabled?

    I don’t have the possibility to check the signals on the board since I don’t have access to them.

    Have you tried disconnecting the CS pin from the LSM6DSV16, maybe it's backpowering it through that. 

    At first, I solved the problem by reconfiguring the SPI GPIOs as inputs

    static int Disable_Imu_Spi_Gpios( void )
    {
        const struct device *gpio0Dev = DEVICE_DT_GET( DT_NODELABEL( gpio0 ) );
    
        if ( !device_is_ready( gpio0Dev ) )
        {
            Error_Managing_Signal( SYSTEM_ERROR_INIT_GPIO, __FILE__, __LINE__ );
            return -1;
        }
    
        if (
            ( gpio_pin_configure( gpio0Dev, IMU_SPI_SCK_PIN, GPIO_INPUT ) < 0 ) ||
            ( gpio_pin_configure( gpio0Dev, IMU_SPI_MOSI_PIN, GPIO_INPUT ) < 0 ) ||
            ( gpio_pin_configure( gpio0Dev, IMU_SPI_MISO_PIN, GPIO_INPUT ) < 0 ) ||
            ( gpio_pin_configure( gpio0Dev, IMU_SPI_CS_PIN, GPIO_INPUT ) < 0 )
            )
    	{
            Error_Managing_Signal( SYSTEM_ERROR_INIT_GPIO, __FILE__, __LINE__ );
    		return -1;
    	}
    
        return 0;
    }

    Now, I tried following your advice: I only disabled the SPI CS, and the problem seems to have disappeared. It really seems like the issue is with the CS. This has never happened to me before. Isn’t the CS supposed to be a high-impedance pin?

Children
Related