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

Can't read "accread" value without enabling reportpr event,

Hi, I have nrf52832 and using QDEC driver. In my application I want to use values accumulated in the acc/accread register for a time of the order of seconds. Since max value for REPORTPER register is 280 samples so for sample rate of 128uS, the time of reporting is around 280*128uS ~= 36mS. Which is too short for my application. And also on every REPORTPER event the acc register is cleared. So I disabled the REPORTPER event and started using nrf_drv_qdec_accumulators_read() function to read values of accread register in a while loop in main function. Following is the code I'm using.

int main(void)
{
	uint32_t err_code;


	err_code = NRF_LOG_INIT(NULL);
	APP_ERROR_CHECK(err_code);

	NRF_LOG_DEFAULT_BACKENDS_INIT();

	NRF_LOG_INFO("fmfbvzfmn");
	NRF_LOG_FLUSH();
// Initialize hardware
	
	nrf_drv_qdec_config_t p_config;
	p_config.reportper          = (nrf_qdec_reportper_t)NRF_QDEC_REPORTPER_DISABLED;
	p_config.sampleper          = (nrf_qdec_sampleper_t)QDEC_CONFIG_SAMPLEPER;
	p_config.psela              = QDEC_CONFIG_PIO_A;
	p_config.pselb              = QDEC_CONFIG_PIO_B;
	p_config.pselled            = QDEC_CONFIG_PIO_LED;
	p_config.ledpre             = QDEC_CONFIG_LEDPRE;
	p_config.ledpol             = (nrf_qdec_ledpol_t)QDEC_CONFIG_LEDPOL;
	p_config.interrupt_priority = QDEC_CONFIG_IRQ_PRIORITY;
	p_config.dbfen              = QDEC_CONFIG_DBFEN;
	p_config.sample_inten       = QDEC_CONFIG_SAMPLE_INTEN;
	

	err_code = nrf_drv_qdec_init(&p_config, qdec_event_handler);
	APP_ERROR_CHECK(err_code);

	NRF_LOG_INFO("QDEC testing started");

int16_t acc;
int16_t accdbl;

        nrf_drv_qdec_enable();// start burst sampling clock, clock will be stopped by REPORTRDY event
	while(1)
	{	nrf_drv_qdec_accumulators_read(&acc, &accdbl);
		NRF_LOG_INFO("acc = %d", acc);
		NRF_LOG_INFO("accdbl = %d", accdbl);
		NRF_LOG_FLUSH();
		nrf_delay_ms(5000);
	}
}

The result of this code is that mostly the value of "acc" variable is 0, and sometimes it gives 1. I'm unable to explain this behavior. I'm using following code to generate the Encoder signal.

void writePin1(bool val)
{	nrf_gpio_pin_write(30,(uint32_t)val);
	nrf_gpio_pin_write(17,(uint32_t)val);
}

void writePin2(bool val)
{	nrf_gpio_pin_write(31,(uint32_t)val);
	nrf_gpio_pin_write(19,(uint32_t)val);
}

int main(void)
{
    uint32_t err_code;


    err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();

    nrf_gpio_cfg_output(17);
    nrf_gpio_cfg_output(19);
    nrf_gpio_cfg_output(30);
    nrf_gpio_cfg_output(31);

nrf_gpio_pin_write(30,0);
nrf_gpio_pin_write(31,0);

uint32_t delay_ms = 50;

 	while(1)
	{	nrf_delay_ms(delay_ms);
		writePin1(1);
		nrf_delay_ms(delay_ms);
		writePin2(1);
		nrf_delay_ms(delay_ms);
		writePin1(0);
		nrf_delay_ms(delay_ms);
		writePin2(0);
	}
}

pin 17 and 19 are LEDs, while 30 and 31 are the signals connected to the other DK running the QDEC code.

Under same scenario, if I enable the REPORTPER event then the outputs are correct but they get reset at every REPORTPER event, which is the behaviour I don't want.

So how to read values from acc/accread registers without enabling the REPORTPER evnt ?

Also, I can see that the ACC register is 32-bit but in the datasheet it says that value range is -1024 to 1023. why does it mean ? the overflow occurs at -1024/1023 or at -2147483648/2147483647 ?

Parents
  • Hi,

    Sorry for the late response.

    When you are using the driver and generate REPORTPER event, then acc data should be read using the event handler (qdec_event_handler). You can’t use nrf_drv_qdec_accumulators_read() like this.

     

     

  • Hi,

    So I'm able to read values of accread and accdblread registers outside the event handler by commenting out the shorts_enable function inside nrf_drv_qdec_init() function. So my questions is resolved but can you please let me know what do these shortcuts do ? like what is meant by the "Shortcut between REPORTRDY event and READCLRACC task" ?

  • The REPORTRDY event triggers an interrupt and notifies you when a non-null report is ready.

    The READCLRACC task moves the value in the ACC register over to the ACCREAD register and then clears the ACC register. The value can then be read out from ACCREAD at the user's discretion while ACC is accumulating new values. 

    Shortcuts can be found in most of the peripherals in the nRF52 family. They are mechanisms that links complementary tasks and events within a specific peripheral (it is a simple form of PPI). The shortcut you talk about links the REPORTRDY event and the READCLRACC task and hence automates the process of moving the ACC value into the ACCREAD register on a REPORTRDY event.

Reply
  • The REPORTRDY event triggers an interrupt and notifies you when a non-null report is ready.

    The READCLRACC task moves the value in the ACC register over to the ACCREAD register and then clears the ACC register. The value can then be read out from ACCREAD at the user's discretion while ACC is accumulating new values. 

    Shortcuts can be found in most of the peripherals in the nRF52 family. They are mechanisms that links complementary tasks and events within a specific peripheral (it is a simple form of PPI). The shortcut you talk about links the REPORTRDY event and the READCLRACC task and hence automates the process of moving the ACC value into the ACCREAD register on a REPORTRDY event.

Children
No Data
Related