This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF5340DK PWM mess with zephyr

Using NCS v1.4.99-dev1.

I have no problem using the PWM with a nRF5340PDK but when i tried it on a nRF5340DK, my program was not working correctly.

I have made a simple example to demonstrate this behavior, 1 LED should blink with PWM and another with the main thread:

/* Includes ------------------------------------------------------------------*/

#include <assert.h>

#include <zephyr.h>

#include <nrfx_pwm.h>
#include <hal/nrf_gpio.h>

/* Private define ------------------------------------------------------------*/

#define LED1_PIN                   NRF_GPIO_PIN_MAP(0,28)
#define LED2_PIN                   NRF_GPIO_PIN_MAP(0,29)
#define LED3_PIN                   NRF_GPIO_PIN_MAP(0,30)
#define LED4_PIN                   NRF_GPIO_PIN_MAP(0,31)

#define PERIOD 25000

#define PWM_DEFAULT_CONFIG_IRQ_PRIORITY 6

/* Private variables ---------------------------------------------------------*/

static nrfx_pwm_t pwm = NRFX_PWM_INSTANCE(1);

static nrf_pwm_values_individual_t sequenceValues[] = {
        {PERIOD / 2, 0x8000 + PERIOD / 2},
};

static nrf_pwm_sequence_t sequence = {
        .values.p_individual = sequenceValues,
        .length              = NRF_PWM_VALUES_LENGTH(sequenceValues),
        .repeats             = 0,
        .end_delay           = 0
};

/* Public functions ----------------------------------------------------------*/

void pwm_init(void)
{
    nrfx_pwm_config_t config = {
            .irq_priority = PWM_DEFAULT_CONFIG_IRQ_PRIORITY,
            .base_clock   = NRF_PWM_CLK_125kHz,
            .count_mode   = NRF_PWM_MODE_UP,
            .top_value    = PERIOD,
            .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
            .step_mode    = NRF_PWM_STEP_AUTO,
            .output_pins[0] = LED2_PIN,
    };

    nrfx_err_t err = nrfx_pwm_init(&pwm, &config, NULL, NULL);
    assert(err == NRFX_SUCCESS);

    nrfx_pwm_simple_playback(&pwm, &sequence, 1, NRFX_PWM_FLAG_LOOP);
}

void main(void)
{
    pwm_init();

    nrf_gpio_cfg_output(LED1_PIN);

    while(1) {
        nrf_gpio_pin_write(LED1_PIN, 1);
        k_sleep(K_MSEC(100));

        nrf_gpio_pin_write(LED1_PIN, 0);
        k_sleep(K_MSEC(100));
    }
}
0246.prj.conf

With a nRF5340PDK, both LED blink but with a nRF5340DK, the LED1 don't blink.

Parents
  • Hi,

    I tested your code on my DK, and it seems like LED1 starts to blink if I comment our pwm_init(). With pwm_init() included, only LED2 blinks. Can you check if this is also true on your board?

    Best regards,
    Jørgen

  • Hi,

    It seems that the problem is caused by some incorrect fields in your PWM config. You do not set output_pins[1]-[3], which will set these to 0. This again will connect P0.00 to the PWM peripheral, preventing it from being controlled correctly from other peripherals.

    By default, P0.00 is used for the 32.768 kHz LF crystal, which is used by RTC and k_sleep to control the sleep modes.

    I verified that both these options resolves the issue:

    1. Set unused pins to NRFX_PWM_PIN_NOT_USED in PWM config:
      void pwm_init(void)
      {
      	nrfx_pwm_config_t config = {
      		.irq_priority = PWM_DEFAULT_CONFIG_IRQ_PRIORITY,
      		.base_clock   = NRF_PWM_CLK_125kHz,
      		.count_mode   = NRF_PWM_MODE_UP,
      		.top_value    = PERIOD,
      		.load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
      		.step_mode    = NRF_PWM_STEP_AUTO,
      		.output_pins[0] = LED2_PIN,
      		.output_pins[1] = NRFX_PWM_PIN_NOT_USED,
      		.output_pins[2] = NRFX_PWM_PIN_NOT_USED,
      		.output_pins[3] = NRFX_PWM_PIN_NOT_USED,
          };
      
          nrfx_err_t err = nrfx_pwm_init(&pwm, &config, NULL, NULL);
          assert(err == NRFX_SUCCESS);
      
          nrfx_pwm_simple_playback(&pwm, &sequence, 1, NRFX_PWM_FLAG_LOOP);
      }
    2. Configure the 32k clock source to use internal RC oscillator, by adding the following configs to prj.conf:
      CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
      CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y

    Best regards,
    Jørgen

Reply
  • Hi,

    It seems that the problem is caused by some incorrect fields in your PWM config. You do not set output_pins[1]-[3], which will set these to 0. This again will connect P0.00 to the PWM peripheral, preventing it from being controlled correctly from other peripherals.

    By default, P0.00 is used for the 32.768 kHz LF crystal, which is used by RTC and k_sleep to control the sleep modes.

    I verified that both these options resolves the issue:

    1. Set unused pins to NRFX_PWM_PIN_NOT_USED in PWM config:
      void pwm_init(void)
      {
      	nrfx_pwm_config_t config = {
      		.irq_priority = PWM_DEFAULT_CONFIG_IRQ_PRIORITY,
      		.base_clock   = NRF_PWM_CLK_125kHz,
      		.count_mode   = NRF_PWM_MODE_UP,
      		.top_value    = PERIOD,
      		.load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
      		.step_mode    = NRF_PWM_STEP_AUTO,
      		.output_pins[0] = LED2_PIN,
      		.output_pins[1] = NRFX_PWM_PIN_NOT_USED,
      		.output_pins[2] = NRFX_PWM_PIN_NOT_USED,
      		.output_pins[3] = NRFX_PWM_PIN_NOT_USED,
          };
      
          nrfx_err_t err = nrfx_pwm_init(&pwm, &config, NULL, NULL);
          assert(err == NRFX_SUCCESS);
      
          nrfx_pwm_simple_playback(&pwm, &sequence, 1, NRFX_PWM_FLAG_LOOP);
      }
    2. Configure the 32k clock source to use internal RC oscillator, by adding the following configs to prj.conf:
      CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
      CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y

    Best regards,
    Jørgen

Children
Related