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

nrfx_pwm_simple_playback() on nRF9160?

Hi, 

I'm using nRF9160 and want to use PWM with the automatic duty sequence feature using DMA, to make an LED "pulse" for example. 

Looking at the documentation for the registers to control PWM, they seem to be the same on nRF9160 as nRF52, so I have tried to use the nrfx library with the nrfx_pwm_simple_playback() function. Though the library seems to be aimed at nRF52, it is included in zephyr and compiles and runs without crashing just fine on nRF9160. 

GPIO and PWM are working in this project, just the nrfx_pwm_simple_playback() isn't working as expected. The output on the scope is showing an unchanging wave at ~10kHz with a duty of around 95%, I have no idea where this configuration comes from. The output from the pins do not seem to be following the sequence I have configured, and I am wondering if this isn't actually supposed to work, or whether my code is just incorrect. 

Is this library expected to work on nRF9160? If not, is there a similarly easy way to get the right result on nRF9160?

I'm using the 1.0.0 DK with SDK 1.5.0 and modem firmware 1.2.3. I've included some code for review. 

Thank you for your help!

nrfx_pwm_config_t conf = {
    .output_pins   = { 
        leds[0].led_pin,    /*  Extracted from DTS, P0.16 for easy scope probing */
        leds[1].led_pin,    /*  Extracted from DTS, P0.3 */
        leds[2].led_pin,    /*  Extracted from DTS, P0.4 */
        leds[3].led_pin     /*  Extracted from DTS, P0.5 */
     },                                   
    .irq_priority  = NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY,
    .base_clock    = NRF_PWM_CLK_1MHz,                    
    .count_mode    = NRF_PWM_MODE_UP,                     
    .top_value     = 1000,                                
    .load_mode     = NRF_PWM_LOAD_COMMON,                 
    .step_mode     = NRF_PWM_STEP_AUTO,                   
    .skip_gpio_cfg = false 
};

nrfx_pwm_init(&_nrfx_pwm_dev, &conf, unused_dummy_handler, NULL);

static nrf_pwm_values_common_t seq_values[32];
for (uint8_t i = 0; i < 8; i++)
{
    seq_values[i] = (i * 2 + 1) * 62;
    seq_values[15-i] = (i * 2 + 1) * 62;
    seq_values[16+i] = (i * 2 + 1) * 62;
    seq_values[31-i] = (i * 2 + 1) * 62;
}

nrf_pwm_sequence_t seq = { .values.p_common = seq_values, .length = 32, .repeats = 1, .end_delay = 0 };

nrfx_pwm_simple_playback(&_nrfx_pwm_dev, &seq, 1, 0);

Parents Reply
  • Hi Simon, 

    I've made a stripped down empty project using that code from MartinBL, and am trying to run it on NRF52 DK now (to check). Weirdly, even this isn't working! nrfx_pwm_init() is always returning an error because it was already previously initialised (somehow).

    I noticed when debugging, if I place a breakpoint inside nrfx_pwm_init(), it will always hit that point BEFORE even entering main() in main.c. Very strange. I am thinking this is something to do with Zephyr executing a whole bunch of stuff before any of my code runs; how can I find out or stop this being pre-initialised? This is preventing me from being able to run nrfx_pwm_init() myself and load in the right config. 


    The picture shoes the breakpoint being hit BEFORE main() in main.c is entered... the state is NRFX_DRV_STATE_UNINITIALIZED. Later when I try to run nrfx_pwm_init() myself, the state is NRFX_DRV_STATE_INITIALIZED so the init fails. 

    I've attached my test project for you to try yourself. Using SDK 1.5.0 and nrf52dk_nrf52832 as the board. 

    If you have any insight into what is going on here, that would be really useful :) Thank you!

    test_proj.zip

Children
Related