Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRFX_QDEC driver "quirks"

Just got NRFX_QDEC driver implementation to work after some issues (using SDK 15.0.0). Thought I might share my experience, maybe help someone else, and give input Nordic for future driver improvements.

1. Since using SDK15, the legacy layer messes things up a bit. Setting NRFX_QDEC_<x> settings in sdk_config.h does not help since they are undefined and replaced by the QDEC_DRIVER_<x> settings. This is a more general issue, not a specific issue to QDEC I think. It's odd that you have to do your settings in legacy layer parts when this has been replaced by NRFX. Anyway, just make sure to change in the right place.

2. I'm not in need of the LED output. However, there is no obvious way of turning that off. The driver occupies a GPIO pin for this and reconfigures it to its liking. After reading posts here at the forum, the workaround was to give value 0xFFFFFFFF as pin number. Doing this will indeed disable that output, but it triggers an assertion in the driver which is not that pretty. Also, the driver assumes you have external pull-ups for your decoder inputs and disables internal pull-ups even though you might have set this before.

The workaround I used that solves all issues mentioned in 2 is to comment out lines that configures gpio from nrfx_qdec.c:

...
//nrf_gpio_cfg_input(p_config->pselled, NRF_GPIO_PIN_NOPULL);
//nrf_gpio_cfg_input(p_config->psela, NRF_GPIO_PIN_NOPULL);
//nrf_gpio_cfg_input(p_config->pselb, NRF_GPIO_PIN_NOPULL);
nrf_qdec_pio_assign(p_config->psela, p_config->pselb, p_config->pselled);
...

psela, pselb pins is configured outside driver instead, in my case using internal pull-ups. I think the best solution would be that information about pull-up/down as well as which pins are used would be provided in nrfx_qdec_config_t.

3. Even though the LED output now is assumed to be disabled, the LEDPRE setting is not disabled and will affect the setting used in SAMPLEPER (too long LEDPRE compared to SAMPLEPER time will block any pulses to be registered it seems). Just trying something, I ended up using LEDPRE=5 since I wanted a short sample time (SAMPLEPER = 0 => 128us)

Regards

Ola

  • Thanks for sharing, I have added it internally as an improvement.

    Best regards,
    Kenneth

  • I totally agree, exactly what I was going to report too.


    Even worse, if the assert is not enabled, setting pselled to 0xFFFFFFFF will make nrf_gpio_cfg() actually write to reg->PIN_CNF[0xFFFFFFFF] which is way out of range!

  • Another bug/quirk (in 15.2.0) is related to using the quadrature driver with reporting disabled (like say you want to read the accumulators manually). The nrfx_qdec_init function incorrectly enables the REPORTRDY_READCLRACC shortcut regardless of whether reporting is enabled or not. Even when disabled, this shortcut apparently is still triggered, interfering with the manual query of ACC. 

    The workaround is to edit nrfx_qdec_init (in nrfx_qdec.c) and move the shortcut line to within the if statement checking if reporting is enabled:

    ...
    nrf_qdec_pio_assign(p_config->psela, p_config->pselb, p_config->pselled);
    nrf_qdec_ledpre_set(p_config->ledpre);
    nrf_qdec_ledpol_set(p_config->ledpol);
    // Line 125: Comment out the original function call here
    //nrf_qdec_shorts_enable(NRF_QDEC_SHORT_REPORTRDY_READCLRACC_MASK);
    ...
    
    if (p_config->reportper != NRF_QDEC_REPORTPER_DISABLED)
    {
        // Add the line back here, within this conditional statement
        // This will ensure the shortcut is only enabled if reporting is also enabled
        nrf_qdec_shorts_enable(NRF_QDEC_SHORT_REPORTRDY_READCLRACC_MASK);
        
        nrf_qdec_reportper_set(p_config->reportper);
        int_mask |= NRF_QDEC_INT_REPORTRDY_MASK;
    }
        

  • Thanks again, I have updated the internal case. And pinged them on progress.

    Best regards,
    Kenneth

  • Thanks! This is affecting 16.0.0 too. With the above fix, a call to nrfx_qdec_accumulators_read() now seems to return the correct number of pulses when reporting is disabled.

Related