nRFX PWM task register address mismatch between nrfx_pwm_simple_playback and nrfx_pwm_task_address_get

I've got an NCS v2.6.1 project on the nRF52832 running a timing chain using PPI for PWM instance 2:

#define STIM_PWM 2
nrfx_pwm_t pwm_instance = NRFX_PWM_INSTANCE(STIM_PWM);

...

uint32_t task_addr = nrfx_pwm_simple_playback(&pwm_instance, &biphasic_seq, 1, NRFX_PWM_FLAG_START_VIA_TASK);
uint32_t exp_addr = nrfx_pwm_task_address_get(&pwm_instance, NRF_PWM_TASK_SEQSTART0);
if (task_addr != exp_addr)
{
    LOG_ERR("Start trigger address unexpected (0x%x != 0x%x)", task_addr, exp_addr);
    fault_config();
}

The output of nrfx_pwm_task_address_get is 0x40022008 as I'd expect from the PWM peripheral registers table for PWM2

However, nrfx_pwm_simple_playback returns 0x40018008, which doesn't seem to match up to any of the addresses in the PWM table. Instead, I found that it seems to be in the address space of the SWI peripheral.

I'm currently using the return from nrfx_pwm_task_address_get in my PPI configuration. Is there a reason to use one or the other with nrfx_gppi_channel_endpoints_setup?

Parents
  • Hi Lepton, 

    Have you tried to reproduce the issue on a simple example ? 
    I did a quick test here on a nRF52840 DK and it seems to work fine: 

    nrfx_pwm_simple_playback return 0x4002200c

    Could you try to test with the attached project (I haven't tested with nRF52832)
    common_mode_pwm.zip
  • Hi Hung,

    I couldn't quite get your project to build, but I modified the sample directly and added the log statement for the address.

    Here's what I get for the nRF52832 devkit:

    And here's the output from a nRF5340 devkit:

    Looks like the base address is correct for the 5340 (0x50023000) but I don't recognise the offset from the table. This is all on NCS v2.6.1

    Here's the return address on the 52832 DK using NCS 2.7.0:

    And using NCS 3.0.2:

    I unfortunately do not have a 52840 DK to compare results with you.

  • I tested Hung's project to run on nRF52832 with SDKv3.0.2 and got the below output, seems OK.

  • That's the same return I'm getting, but shouldn't the return address be 0x40022008 based on the PWM registers table?

    The 0x40018000 is the base address for the SWI peripheral instead. I'm trying to understand that discrepancy. 

  • it looks like in nrfx_pwm.c->start_playback-> you have this code

        if (flags & NRFX_PWM_FLAG_START_VIA_TASK)
        {
            uint32_t starting_task_address =
                nrfy_pwm_task_address_get(p_instance->p_reg, nrfy_pwm_seqstart_task_get(seq_id));
    
    #if defined(USE_DMA_ISSUE_WORKAROUND)
            // To "protect" the initial DMA transfer it is required to start
            // the PWM by triggering the proper task from EGU interrupt handler,
            // it is not safe to do it directly via PPI.
            p_cb->starting_task_address = starting_task_address;
            nrf_egu_int_enable(DMA_ISSUE_EGU, nrf_egu_channel_int_get(p_instance->instance_id));
            return nrf_egu_task_address_get(DMA_ISSUE_EGU,
                                            nrf_egu_trigger_task_get(p_instance->instance_id));
    #else
            return starting_task_address;
    #endif
        }

    So it looks like when NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED is enabled with CONFIG_NRF52_ANOMALY_109_WORKAROUND then we have USE_DMA_ISSUE_WORKAROUND makes the workaround via EGU instead of PPI, so that could be the reason to see different task address. 

Reply
  • it looks like in nrfx_pwm.c->start_playback-> you have this code

        if (flags & NRFX_PWM_FLAG_START_VIA_TASK)
        {
            uint32_t starting_task_address =
                nrfy_pwm_task_address_get(p_instance->p_reg, nrfy_pwm_seqstart_task_get(seq_id));
    
    #if defined(USE_DMA_ISSUE_WORKAROUND)
            // To "protect" the initial DMA transfer it is required to start
            // the PWM by triggering the proper task from EGU interrupt handler,
            // it is not safe to do it directly via PPI.
            p_cb->starting_task_address = starting_task_address;
            nrf_egu_int_enable(DMA_ISSUE_EGU, nrf_egu_channel_int_get(p_instance->instance_id));
            return nrf_egu_task_address_get(DMA_ISSUE_EGU,
                                            nrf_egu_trigger_task_get(p_instance->instance_id));
    #else
            return starting_task_address;
    #endif
        }

    So it looks like when NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED is enabled with CONFIG_NRF52_ANOMALY_109_WORKAROUND then we have USE_DMA_ISSUE_WORKAROUND makes the workaround via EGU instead of PPI, so that could be the reason to see different task address. 

Children
No Data
Related