PWM not working after upgrade to nrf Connect SDK 1.9.1

Since upgrading to nrf Connect SDK 1.9.1, I no longer have PWM output. No errors returned when calling pwm_pin_set_usec, yet no output.

I tried upgrading to the latest nrf Connect SDK (2.2.0), thinking that perhaps a bug was fixed, but the number of changes (include paths, etc) was too daunting.

Parents
  • Hi,

    Can you post the part of your code where you use pwm_pin_set_usec()?

    Regards,
    Sigurd Hellesvik

  • #define AFE_CLOCK_NODE  DT_ALIAS(afe_clock)

    #if DT_NODE_HAS_STATUS(AFE_CLOCK_NODE, okay)
    #ifndef DT_PWMS_LABEL
    #define AFE_CLOCK_LABEL DT_NODELABEL(AFE_CLOCK_NODE)
    #else
    #define AFE_CLOCK_LABEL DT_PWMS_LABEL(AFE_CLOCK_NODE)
    #endif
    #define AFE_CLOCK_CHANNEL   DT_PWMS_CHANNEL(AFE_CLOCK_NODE)
    #define AFE_CLOCK_FLAGS DT_PWMS_FLAGS(AFE_CLOCK_NODE)
    #else
    #error "Unsupported board: afe-clock devicetree alias is not defined"
    #define AFE_CLOCK_LABEL ""
    #define AFE_CLOCK_CHANNEL   0
    #define AFE_CLOCK_FLAGS 0
    #endif
     
        int ret = 0;

        _AfeClock_dev = device_get_binding(AFE_CLOCK_LABEL);
        if (!_AfeClock_dev) {
            Z_LOG(LOG_LEVEL_ERR, "Error: didn't find %s device.", AFE_CLOCK_LABEL);
            ret |= 0x1;
        }
     
        retpwm_pin_set_usec(AfeClock_dev, AFE_CLOCK_CHANNEL,
                       PWM_USEC(period), PWM_USEC(width), AFE_CLOCK_FLAGS);
        if (ret) {
            Z_LOG(LOG_LEVEL_ERR, "Error %d: failed to set pulse width.", ret);
        }
  • csteaderman said:
    I am now able to get my PWM signal out!

    Good to hear!

    csteaderman said:
    Should I create a new ticket or address it here?

    We can continue here.

    csteaderman said:
    Any insights?

    Can you share your pinctrl configuration for SPI?

    Our central nRF pairing sample uses SPI with ACTIVE LOW cs-gpios.
    Is this what you need?

    Regards,
    Sigurd Hellesvik

  • Here are the relevant sections from the pinctrl file and device tree files.

    	spi1_default: spi1_default {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 16)>,
    				<NRF_PSEL(SPIM_MOSI, 0, 15)>,
    				<NRF_PSEL(SPIM_MISO, 0, 14)>;
    		};
    	};
    
    	spi1_sleep: spi1_sleep {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 16)>,
    				<NRF_PSEL(SPIM_MOSI, 0, 15)>,
    				<NRF_PSEL(SPIM_MISO, 0, 14)>;
    			low-power-enable;
    		};
    	};

    &spi1 {
    	compatible = "nordic,nrf-spi";
    	status = "okay";
    	pinctrl-0 = <&spi1_default>;
    	pinctrl-1 = <&spi1_sleep>;
    	pinctrl-names = "default", "sleep";
    	cs-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
    	afe4490: afe4490@0 {
    		compatible = "vnd,spi-device";
    		reg = <0>;
    		spi-max-frequency = <4000000>;
    		label = "afe4490";
    	};
    };
    

  • Can you share your SPI code?

    Or even better, a minimal sample with only SPI communication so I can try to replicate the issue on my end?

    Regards,
    Sigurd Hellesvik

  • Here is my SPI code. I have tested both the non-dts and the dts version of the functions, both perform the same with the CS being inverted.

    /* spi.c - SPI wrapper */
    
    #include <stdint.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/spi.h>
    #include "spi.h"
    
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(spi_wrapper, CONFIG_LOG_DEFAULT_LEVEL);
    
    static struct spi_buf rx;
    const static struct spi_buf_set rx_bufs = {
    	.buffers = &rx,
    	.count = 1,
    };
    
    static struct spi_buf tx;
    const static struct spi_buf_set tx_bufs = {
    	.buffers = &tx,
    	.count = 1,
    };
    
    static const struct spi_config spi_cfg = {
    	.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB,
    	.frequency = 4000000,
    	.slave = 0,
        .cs = &(struct spi_cs_control) {
            .delay = 1,
            .gpio.pin = 18,
            .gpio.dt_flags = GPIO_ACTIVE_LOW,
            .gpio.port = DEVICE_DT_GET(DT_NODELABEL(gpio0)),
        },
    };
    
    int spi_send(const struct device *spi,
            const uint8_t *data, size_t len)
    {
        tx.buf = (void*)data;
        tx.len = len;
    
    	return spi_write(spi, &spi_cfg, &tx_bufs);
    }
    
    int spi_send_dt(const struct spi_dt_spec *spi_dt,
        const uint8_t *data, size_t len)
    {
        tx.buf = (void*)data;
        tx.len = len;
    
    	return spi_write_dt(spi_dt, &tx_bufs);
    }
    
    int spi_recv(const struct device *spi,
        uint8_t *data, size_t len)
    {
        rx.buf = data;
        rx.len = len;
    
    	return spi_read(spi, &spi_cfg, &rx_bufs);
    }
    
    int spi_sendrecv(const struct device *spi,
        const uint8_t *writedata, uint8_t *readdata,
        size_t len)
    {
        tx.buf = (void*)writedata;
        tx.len = len;
        rx.buf = readdata;
        rx.len = len;
    
    	return spi_transceive(spi, &spi_cfg, &tx_bufs, &rx_bufs);
    }
    
    int spi_sendrecv_dt(const struct spi_dt_spec *spi_dt,
        const uint8_t *writedata, uint8_t *readdata,
        size_t len)
    {
        tx.buf = (void*)writedata;
        tx.len = len;
        rx.buf = readdata;
        rx.len = len;
    
    	return spi_transceive_dt(spi_dt, &tx_bufs, &rx_bufs);
    }
    

  • Some additional data. I think that my configuration of the DTS is correct. If I breakpoint in my SPI code at line 50 above, I can watch the spi_dt variable. If I set the cs-gpios to GPIO_ACTIVE_HIGH, I get the following:

    If I set the cs_gpios to GPIO_ACTIVE_LOW, I get the following:

    So, I think that I am properly setting up the device tree, it just seems that the code that is supposed to interpret the dt_flags field is not honoring it when configuring the chip select. This is quite frustrating since I am so close to getting my device to work, but this one thing makes it completely useless.

Reply
  • Some additional data. I think that my configuration of the DTS is correct. If I breakpoint in my SPI code at line 50 above, I can watch the spi_dt variable. If I set the cs-gpios to GPIO_ACTIVE_HIGH, I get the following:

    If I set the cs_gpios to GPIO_ACTIVE_LOW, I get the following:

    So, I think that I am properly setting up the device tree, it just seems that the code that is supposed to interpret the dt_flags field is not honoring it when configuring the chip select. This is quite frustrating since I am so close to getting my device to work, but this one thing makes it completely useless.

Children
  • Hi,

    csteaderman said:
    So, I think that I am properly setting up the device tree,

    I agree; it looks like the devicetree is

    A colleague of mine has an NCS-SPI-Master-Slave-Example.

    In this sample,  it looks like he has to get the GPIO configuration manually from the devicetree to use for his SPI functions:

    It looks like you are creating spi_cfg manually in your code posted below.
    But you set the CS pin to ACTIVE_LOW in your code manually as well, so I would think this should be enough hmm.

    So to test if ACTIVE_HIGH/ACTIVE_LOW works, I took the NCS-SPI-Master-Slave-Example sample.
    I built it for nRF Connect SDK v2.2.0 and ran it on an nRF52840DK.

    Then I change the CS Pin to LED3:

    diff --git a/nrf52840dk_nrf52840.overlay b/nrf52840dk_nrf52840.overlay
    index 84cbaaa..a3addf7 100644
    --- a/nrf52840dk_nrf52840.overlay
    +++ b/nrf52840dk_nrf52840.overlay
    @@ -41,7 +41,7 @@ my_spi_master: &spi1 {
            status = "okay";
            pinctrl-0 = <&spi1_default>;
            pinctrl-1 = <&spi1_sleep>;
    -       cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
    +       cs-gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;^M
            reg_my_spi_master: spi-dev-a@0 {
                    reg = <0>;
            };
    @@ -53,4 +53,4 @@ my_spi_slave: &spi2 {
            pinctrl-0 = <&spi2_default>;
            pinctrl-1 = <&spi2_sleep>;
            def-char = <0x00>;
    -};
    \ No newline at end of file
    

    I observe that LED3 is off.

    Then I change the CS pin to ACTIVE_HIGH:

    diff --git a/nrf52840dk_nrf52840.overlay b/nrf52840dk_nrf52840.overlay
    index 84cbaaa..9633808 100644
    --- a/nrf52840dk_nrf52840.overlay
    +++ b/nrf52840dk_nrf52840.overlay
    @@ -41,7 +41,7 @@ my_spi_master: &spi1 {
            status = "okay";
            pinctrl-0 = <&spi1_default>;
            pinctrl-1 = <&spi1_sleep>;
    -       cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
    +       cs-gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;^M
            reg_my_spi_master: spi-dev-a@0 {
                    reg = <0>;
            };
    @@ -53,4 +53,4 @@ my_spi_slave: &spi2 {
            pinctrl-0 = <&spi2_default>;
            pinctrl-1 = <&spi2_sleep>;
            def-char = <0x00>;
    

    When I rebuild and flash this time, I observe that LED3 is on.

    From this, it looks like the CS pin ACTIVE_HIGH configuration works for this sample.

    Was this helpful?

    Regards,
    Sigurd Hellesvik

Related