arduino / arduino/ArduinoCore-mbed
Access to nRF528x hardware decoder
- Dominant language
- C
- Stars
- 411
- Forks
- 225
- PR merge metrics
- No merged PRs in 30d
Description
### Subject of the issue
I'd like to gain access to the hardware decoder inside the nrF528x, right now I'm reading a quadrature encoder using interrupts on pins 4 (for channel A) and 6 (for channel B), using the InterruptIn mbed instructions, starting from a mbed library found on mbed site, and adapting it to work under arduino core, basically by adding mbed:: before mbed instructions and some callbacks.
```
mbed::InterruptIn sqwA;
mbed::InterruptIn sqwB;
mbed::InterruptIn pulZero;
```
```
sqwA.rise(mbed::callback(this, &QEI::encode));
sqwA.fall(mbed::callback(this, &QEI::encode));
sqwB.rise(mbed::callback(this, &QEI::encode));
sqwB.fall(mbed::callback(this, &QEI::encode));
pulZero.rise(mbed::callback(this, &QEI::index));
```
The code works great for frequencies under 7 kHz, pulse count is correct and also frequency and speed calculations, but when i increase the motor speed i start to lose pulses and the count (and also frequency and speed calculation) goes wrong. So I wanted to see if the problem was the interrupt frequency, maybe is too slow for that motor speed, and I thought that using the hardware decoder was a good option because in theory it gives me the pulse count without any software calculation on the main loop so it should be the fastest option. I started from the example on the nordic SDK 15.0 for the QDEC and a wrote a little sketch to see if I was able to compile it:
```
#include
#include
#include "nrfx_gpiote.h"
#include
#include
#include
#define NRFX_QDEC_ENABLED 1
#define NRFX_QDEC_CONFIG_REPORTPER NRF_QDEC_REPORTPER_120
#define NRFX_QDEC_CONFIG_SAMPLEPER NRF_QDEC_SAMPLEPER_256us
#define NRFX_QDEC_CONFIG_PIO_A (4u)
#define NRFX_QDEC_CONFIG_PIO_B (6u)
#define NRFX_QDEC_CONFIG_PIO_LED 0xFFFFFFFF
#define NRFX_QDEC_CONFIG_LEDPRE 0
#define NRFX_QDEC_CONFIG_LEDPOL NRF_QDEC_LEPOL_ACTIVE_LOW
#define NRFX_QDEC_CONFIG_IRQ_PRIORITY 2
#define NRFX_QDEC_CONFIG_DBFEN NRF_QDEC_DBFEN_DISABLE
#define NRFX_QDEC_CONFIG_SAMPLE_INTEN NRF_QDEC_INT_SAMPLERDY_MASK
static volatile uint32_t m_accdblread;
static volatile int32_t m_accread;
nrfx_qdec_config_t cfg =
{
cfg.reportper = NRFX_QDEC_CONFIG_REPORTPER,
cfg.sampleper = NRFX_QDEC_CONFIG_SAMPLEPER,
cfg.psela = NRFX_QDEC_CONFIG_PIO_A,
cfg.pselb = NRFX_QDEC_CONFIG_PIO_B,
cfg.pselled = NRFX_QDEC_CONFIG_PIO_LED,
cfg.ledpre = NRFX_QDEC_CONFIG_LEDPRE,
cfg.ledpol = NRFX_QDEC_CONFIG_LEDPOL,
cfg.dbfen = NRFX_QDEC_CONFIG_DBFEN,
cfg.sample_inten = NRF_QDEC_INT_SAMPLERDY_MASK,
cfg.interrupt_priority = NRFX_QDEC_CONFIG_IRQ_PRIORITY};
nrfx_qdec_config_t *cfgPoint = &cfg;
static void gpio_config(void)
{
nrf_gpio_cfg_input(NRFX_QDEC_CONFIG_PIO_A, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(NRFX_QDEC_CONFIG_PIO_B, NRF_GPIO_PIN_PULLUP);
}
static void qdec_event_handler(nrfx_qdec_event_t event)
{
if (event.type == NRF_QDEC_EVENT_REPORTRDY)
{
m_accdblread = event.data.report.accdbl;
m_accread = event.data.report.acc;
nrfx_qdec_disable();
}
}
static void qdec_config(void)
{
uint32_t err_code;
// Initialize hardware
err_code = nrfx_qdec_init(cfgPoint, qdec_event_handler);
APP_ERROR_CHECK(err_code);
Serial.println("QDEC testing started");
nrfx_qdec_enable(); // Event and corresponding interrupt are enabled.
Serial.println("nrf_drv_qdec_enable");
}
void setup()
{
Serial.begin(9600);
gpio_config();
qdec_config();
}
void loop()
{
Serial.println(m_accdblread);
Serial.println(m_accread);
delay(100);
}
```
But the problem as commented on arduino/ArduinoCore-nRF528x-mbedos#58, I get the compiler error:
```
c:\Users\a.rondon\Documents\Arduino\Arduino_VSC\nano33BLE_hardwareDecoder/nano33BLE_hardwareDecoder.ino:65: undefined reference to `nrfx_qdec_init'
c:\Users\a.rondon\Documents\Arduino\Arduino_VSC\nano33BLE_hardwareDecoder/nano33BLE_hardwareDecoder.ino:69: undefined reference to `nrfx_qdec_enable'
```
and as stated on arduino/ArduinoCore-nRF528x-mbedos#58, the src files for `nrfx_qdec.h` are missing, I tried copying the files from nordic SDK 15 directly on the sketch folder as suggested by @facchinm but that didn't work either, I took a look at arduino/ArduinoCore-nRF528x-mbedos#72 and what @Polldo said here https://github.com/arduino/ArduinoCore-nRF528x-mbedos/issues/58#issuecomment-625179806, but I think I'm using the right file `#include `
So, if there is something I could try to solve this problem? There are some mbed API's to read the decoder directly??
Thanks for all the help you could provide guys!!
### My workbench
* Arduino nano 33 BLE sense
* Board version V2.0, with MCU nRF52840 (32-bit ARM® Cortex™-M4 CPU)
* Encoder connected to pins P1_14 and P1_15 (D4 and D6)
* Using VsCode with arduino extension
### Expected behavior
Well I'd like to use the hardware decoder inside the arduino nano 33 BLE
### Actual behavior
The code doesn't compile because it can find the source files for nrfx_qdec.h
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the nrfx_qdec.h usage in the provided sketch and the missing source-file discussion in ArduinoCore-nRF528x-mbedos#58, then compare it with the Nordic SDK 15.0 QDEC example and issue #72. The work is done when the sketch links successfully and can access the nRF52840 hardware decoder on the stated encoder pins.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100