Trying to set up PWMs on a custom board

Hi,

I am trying to set up PWMs on a custom board, but I am not able to observe the outputs using an oscilloscope (pins are constantly at 0V).  The PWM channels should be set to P0.26 and P0.27.  

Here is my device tree:

// Copyright (c) 2022 Nordic Semiconductor ASA
// SPDX-License-Identifier: Apache-2.0

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>

/ {
	model = "10_000010_00_Throttle_Splitter";
	compatible = "fifteen-motors,10-000010-00-throttle-splitter";

	chosen {
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,code-partition = &slot0_partition;
	};

	leds {
		compatible = "gpio-leds";
		ledbar0: led_0 {
			gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
			label = "LED Bar 0";
		};
		ledbar1: led_1 {
			gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
			label = "LED Bar 1";
		};
		ledbar2: led_2 {
			gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
			label = "LED Bar 2";
		};
		ledbar3: led_3 {
			gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
			label = "LED Bar 3";
		};
		ledbuttonl: led_l {
			gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
			label = "LED Button Left";
		};
		ledbuttonr: led_r {
			gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
			label = "LED Button Right";
		};
	};

	pwmdevs {
		compatible = "pwm-leds";
		pwm_dev0: pwm_dev0 {
		 	pwms = <&pwm0 26  PWM_USEC(1000) PWM_POLARITY_NORMAL>;
		};
		pwm_dev1: pwm_dev1 {
			pwms = <&pwm1 27 PWM_USEC(1000) PWM_POLARITY_NORMAL>;
		};
	};
	
	
	buttons {
		compatible = "gpio-keys";
		buttonl: button_l {
			gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			label = "Push button switch left";
		};
		buttonr: button_r {
			gpios = <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			label = "Push button switch right";
		};
	};

	/* These aliases are provided for compatibility with samples */
	aliases {
		buttonl = &buttonl;
		buttonr = &buttonr;
		ledbar0 = &ledbar0;
		ledbar1 = &ledbar1;
		ledbar2 = &ledbar2;
		ledbar3 = &ledbar3;
		ledbuttonl = &ledbuttonl;
		ledbuttonr  = &ledbuttonr;
		mcfront = &pwm_dev0;
		mcrear = &pwm_dev1;
	};

};

&gpiote {
	status = "okay";
};

&gpio0 {
	status = "okay";
};

&gpio1 {
	status = "okay";
};

&pwm0 {
	status = "okay";
	ch0-pin = <26>;
	// ch0-inverted;
};

&pwm1 {
	status = "okay";
	ch0-pin = <27>;
	// ch0-inverted;
};


&flash0 {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x0 0xc000>;
		};
		slot0_partition: partition@c000 {
			label = "image-0";
			reg = <0xc000 0x72000>;
		};
		slot1_partition: partition@7e000 {
			label = "image-1";
			reg = <0x7e000 0x72000>;
		};
		scratch_partition: partition@f0000 {
			label = "image-scratch";
			reg = <0xf0000 0xa000>;
		};
		storage_partition: partition@fa000 {
			label = "storage";
			reg = <0xfa000 0x6000>;
		};
	};
};

In the main.c file, I am setting up the PWMs via the following:

// Parameters for PWM control
static const struct pwm_dt_spec pwm_front = PWM_DT_SPEC_GET(DT_ALIAS(mcfront));
static const struct pwm_dt_spec pwm_rear = PWM_DT_SPEC_GET(DT_ALIAS(mcrear));
#define PWM_PERIOD PWM_MSEC(1U)   // set PWMs to 10kHz

And have the following in my main loop:

// Set up PWMs
	if (!device_is_ready(pwm_front.dev) || !device_is_ready(pwm_rear.dev)) {
		return;
	}
	ret = pwm_set_dt(&pwm_front, PWM_PERIOD, PWM_PERIOD / 2U);
	ret = pwm_set_dt(&pwm_rear, PWM_PERIOD, PWM_PERIOD / 2U);

	// Initialize the LEDs and confirm they are ready to use
	if (!device_is_ready(led0.port)) {
		return;
	}

I have "supported:- pwm" in my YAML file, and "CONFIG_PWM=y" in my project config file.  

Parents Reply Children
  • /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <device.h>
    #include <drivers/pwm.h>
    #include <drivers/gpio.h>
    #include <drivers/pwm.h>
    // #include <drivers/adc.h>
    
    // 
    #define DEBOUNCE_CYCLES 5
    
    // Parameters for PWM control
    static const struct pwm_dt_spec pwm_front = PWM_DT_SPEC_GET(DT_ALIAS(mcfront));
    static const struct pwm_dt_spec pwm_rear = PWM_DT_SPEC_GET(DT_ALIAS(mcrear));
    #define PWM_PERIOD PWM_MSEC(1U)   // set PWMs to 10kHz
    
    // Variables for power status
    static int powerLevel;
    static int debounceCounter;
    
    
    // Define the pins in the Nordic connection
    // Bar Light
    #define LED0_NODE DT_ALIAS(ledbar0)
    #define LED1_NODE DT_ALIAS(ledbar1)
    #define LED2_NODE DT_ALIAS(ledbar2)
    #define LED3_NODE DT_ALIAS(ledbar3)
    // Button lights
    #define LEDBL_NODE DT_ALIAS(ledbuttonl)
    #define LEDBR_NODE DT_ALIAS(ledbuttonr)
    // Generate structs for LEDs
    static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
    static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
    static const struct gpio_dt_spec led2 = GPIO_DT_SPEC_GET(LED2_NODE, gpios);
    static const struct gpio_dt_spec led3 = GPIO_DT_SPEC_GET(LED3_NODE, gpios);
    static const struct gpio_dt_spec ledBL = GPIO_DT_SPEC_GET(LEDBL_NODE, gpios);
    static const struct gpio_dt_spec ledBR = GPIO_DT_SPEC_GET(LEDBR_NODE, gpios);
    
    
    // // switches
    #define SW0_NODE	DT_ALIAS(buttonl)
    #define SW1_NODE	DT_ALIAS(buttonr)
    static const struct gpio_dt_spec button0 = GPIO_DT_SPEC_GET(SW0_NODE, gpios);
    static const struct gpio_dt_spec button1 = GPIO_DT_SPEC_GET(SW1_NODE, gpios);
    
    // Define an interupt for the button being pressed
    void button1_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
    {
    	if (debounceCounter < 1){	
    		gpio_pin_set_dt(&ledBR, 1);
    		powerLevel++;
    		if(powerLevel > 4) {
    			powerLevel = 4;
    		} 
    		debounceCounter = DEBOUNCE_CYCLES;
    	}
    }
    
    void button0_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
    {
        if (debounceCounter < 1){	
    		gpio_pin_set_dt(&ledBL, 1);
    		powerLevel--;
    		if(powerLevel < 0) {
    			powerLevel = 0;
    		}
    		debounceCounter = DEBOUNCE_CYCLES;
    	}
    }
    
    void setLedBar(){
    	if(powerLevel > 0) {
    		gpio_pin_set_dt(&led0, 1);
    	} else {
    		gpio_pin_set_dt(&led0, 0);
    	}
    	if(powerLevel > 1) {
    		gpio_pin_set_dt(&led1, 1);
    	} else {
    		gpio_pin_set_dt(&led1, 0);
    	}
    	if(powerLevel > 2) {
    		gpio_pin_set_dt(&led2, 1);
    	} else {
    		gpio_pin_set_dt(&led2, 0);
    	}
    	if(powerLevel > 3) {
    		gpio_pin_set_dt(&led3, 1);
    	} else {
    		gpio_pin_set_dt(&led3, 0);
    	}
    }
    
    // Define a variable of type static struct gpio_callback for buttons 1 and 2
    static struct gpio_callback button0_cb_data;
    static struct gpio_callback button1_cb_data;
    
    void main(void)
    {
    
    	int ret;
    	powerLevel = 0;
    	debounceCounter = 2;
    	
    	// Set up PWMs
    	if (!device_is_ready(pwm_front.dev) || !device_is_ready(pwm_rear.dev)) {
    		return;
    	}
    	ret = pwm_set_dt(&pwm_front, PWM_PERIOD, PWM_PERIOD / 2U);
    	if(ret > 0) {
    		return;
    	}
    	ret = pwm_set_dt(&pwm_rear, PWM_PERIOD, PWM_PERIOD / 2U);
    	if(ret > 0) {
    		return;
    	}
    	
    
    	// Initialize the LEDs and confirm they are ready to use
    	if (!device_is_ready(led0.port)) {
    		return;
    	}
    	
    	ret = gpio_pin_configure_dt(&led0, GPIO_OUTPUT_ACTIVE);
    	ret += gpio_pin_configure_dt(&led1, GPIO_OUTPUT_ACTIVE);
    	ret += gpio_pin_configure_dt(&led2, GPIO_OUTPUT_ACTIVE);
    	ret += gpio_pin_configure_dt(&led3, GPIO_OUTPUT_ACTIVE);
    	ret += gpio_pin_configure_dt(&ledBL, GPIO_OUTPUT_ACTIVE);
    	ret += gpio_pin_configure_dt(&ledBR, GPIO_OUTPUT_ACTIVE);
    	if (ret < 0) {
    		return;
    	}
    
    	// Verify that the device is ready for use 
    	if (!device_is_ready(button0.port)) {
    		return;
    	}
    	if (!device_is_ready(button1.port)) {
    		return;
    	}
    	ret = gpio_pin_configure_dt(&button0, GPIO_INPUT);
    	ret = gpio_pin_configure_dt(&button1, GPIO_INPUT);
    	if (ret < 0) {
    		return;
    	}
    
    
    	setLedBar();
    
    	// Configure the interrupt for button 0 
    	ret = gpio_pin_interrupt_configure_dt(&button0, GPIO_INT_EDGE_FALLING );
    	gpio_init_callback(&button0_cb_data, button0_pressed, BIT(button0.pin)); 
    	gpio_add_callback(button0.port, &button0_cb_data);
    
    	// Configure the interrupt for button 1 
    	ret = gpio_pin_interrupt_configure_dt(&button1, GPIO_INT_EDGE_FALLING );
    	gpio_init_callback(&button1_cb_data, button1_pressed, BIT(button1.pin)); 
    	gpio_add_callback(button1.port, &button1_cb_data);
    
    
    
    	// Main loop
    	while(1){
    
            k_msleep(100); // Put the main thread to sleep for 100ms for power optimization
    		// Reset LEDs
    		setLedBar();
    		// Lower the debound counter
    		--debounceCounter;
    		if(debounceCounter < 0){
    			debounceCounter = 0;
    			gpio_pin_set_dt(&ledBL, 0);
    			gpio_pin_set_dt(&ledBR, 0);
    		};
    
    	}
    }
    

  • Try to edit blinky_pwm to use your pwm_dev0 node instead. It would be very helpful to know if that works.

Related