Definition "extern pcnt_dev_t PCNT" + ISR

onpa_esp32
Posts: 8
Joined: Tue Aug 29, 2017 7:41 am

Definition "extern pcnt_dev_t PCNT" + ISR

Postby onpa_esp32 » Fri Sep 01, 2017 3:26 pm

Folks,
I'm playing with Pulse Counter in ESP32.
I'm able count pulses now, but can't invoke ISR. Resp. - I'm able to define ISR, but program probably get-lock in the ISR and never release it.
I'm trying to find the root-cause. Maybe, the flag for finishing interrupt is not cleared.
So, I would like to clear the flag manually, infortunatelly can't compile foloving code :

(if I remove registration of ISR routine "pcnt_example_intr_handler", code works properly. After registration ISR and fulfillling condition - the ISR is executed but the program is completely frozen :( )

Code: Select all

#include "driver/pcnt.h"

/* LED pin */
byte ledPin = 12;
/* pin that is attached to interrupt */
byte interruptPin = 14;
/* hold the state of LED when toggling */
byte pulsePin = 13;

int16_t flow0Counter = 45;

volatile byte state = LOW;

#define PCNT_TEST_UNIT     PCNT_UNIT_0
#define PCNT_H_LIM_VAL     10
#define PCNT_L_LIM_VAL     -10
#define PCNT_THRESH1_VAL   5
#define PCNT_THRESH0_VAL   -5

void setup() {
  pinMode(ledPin, OUTPUT);
  /* set the interrupt pin as input pullup*/
  pinMode(interruptPin, INPUT_PULLUP);
  /* attach interrupt to the pin
  function blink will be invoked when interrupt occurs
  interrupt occurs whenever the pin change value */
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
  pinMode(pulsePin,INPUT_PULLUP);
  Serial.begin(115200);
  Serial.println("");
  initPcnt();
}

void loop() {
  Serial.println("Smycka");
  readPcntCounter_0();
  delay(1000);
}

/* interrupt function toggle the LED */
/* fungovalo do cca 300kHz vstupního kmitočtu */
void blink() {
  state = !state;
  digitalWrite(ledPin, state);
}

/* interrupt function for PCNT */
void IRAM_ATTR pcnt_example_intr_handler(void* arg) {
  uint32_t intr_status;
  intr_status = PCNT.int_st.val;

  int i;

  for(i = 0; i < PCNT_UNIT_MAX; i++) {
      if(intr_status & (BIT(i))) {
          PCNT.int_clr.val = BIT(i);
      }
  }
}

//initialize counter for flow0
void initPcnt() {

  esp_err_t error;

  Serial.println("Inicializace pulse totalizeru");

  pcnt_config_t pcnt_config = {
    pulsePin, // Pulse input gpio_num, if you want to use gpio16, pulse_gpio_num = 16, a negative value will be ignored
    PCNT_PIN_NOT_USED, // Control signal input gpio_num, a negative value will be ignored
    PCNT_MODE_KEEP, // PCNT low control mode
    PCNT_MODE_KEEP, // PCNT high control mode
    PCNT_COUNT_INC, // PCNT positive edge count mode
    PCNT_COUNT_DIS, // PCNT negative edge count mode
    PCNT_H_LIM_VAL, // Maximum counter value
    PCNT_L_LIM_VAL, // Minimum counter value
    PCNT_TEST_UNIT, // PCNT unit number
    PCNT_CHANNEL_0, // the PCNT channel
  };

  if(pcnt_unit_config(&pcnt_config) == ESP_OK) //init unit
    Serial.println("Config Unit_0 = ESP_OK");

  /*Configure input filter value*/
  pcnt_set_filter_value(PCNT_TEST_UNIT, 100);
  /*Enable input filter*/
  pcnt_filter_enable(PCNT_TEST_UNIT);

  /*Set value for watch point thresh1*/
  pcnt_set_event_value(PCNT_TEST_UNIT, PCNT_EVT_THRES_1, PCNT_THRESH1_VAL);
  /*Enable watch point event of thresh1*/
  //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_THRES_1);
  pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_THRES_1);
  /*Set value for watch point thresh0*/
  pcnt_set_event_value(PCNT_TEST_UNIT, PCNT_EVT_THRES_0, PCNT_THRESH0_VAL);
  /*Enable watch point event of thresh0*/
  //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_THRES_0);
  pcnt_event_disable(PCNT_TEST_UNIT, PCNT_EVT_THRES_0);
  /*Enable watch point event of h_lim*/
  //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_H_LIM);
  pcnt_event_disable(PCNT_TEST_UNIT, PCNT_EVT_H_LIM);
  /*Enable watch point event of l_lim*/
  //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_L_LIM);
  pcnt_event_disable(PCNT_TEST_UNIT, PCNT_EVT_L_LIM);
  /*Enable watch point event of zero*/
  //pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_ZERO);
  pcnt_event_enable(PCNT_TEST_UNIT, PCNT_EVT_ZERO);

  /*Pause counter*/
  pcnt_counter_pause(PCNT_TEST_UNIT);
  /*Reset counter value*/
  pcnt_counter_clear(PCNT_TEST_UNIT);
  /*Register ISR handler*/
  pcnt_isr_register(pcnt_example_intr_handler, NULL, 0, NULL);
  /*Enable interrupt for PCNT unit*/
  pcnt_intr_enable(PCNT_TEST_UNIT);
  /*Resume counting*/
  pcnt_counter_resume(PCNT_TEST_UNIT);

}

void readPcntCounter_0() {
  if(pcnt_get_counter_value(PCNT_UNIT_0, &flow0Counter) == ESP_OK)
  Serial.println("Read pcnt unit 0");
  delay(10);
  Serial.print("flow0Counts = ");
  Serial.println(flow0Counter);
}
Why PCNT variable is not visible ?

Result of compilation :

platformio run
Collected 14 compatible libraries
Looking for dependencies...
No dependencies
Compiling .pioenvs\lolin32\src\Interrupt.ino.o
In file included from C:\users\fft\.platformio\packages\framework-arduinoespressif32\tools\sdk\include\driver/drive
r/pcnt.h:12:0,
from D:/Projects/ESP32/Interrupt2/src/Interrupt.ino:1:

C:\users\fft\.platformio\packages\framework-arduinoespressif32\tools\sdk\include\soc/soc/pcnt_struct.h:171:19: error: 'pcnt_dev_t PCNT', declared using anonymous type, is used but never defined [-fpermissive]
extern pcnt_dev_t PCNT;
^
C:\users\fft\.platformio\packages\framework-arduinoespressif32\tools\sdk\include\soc/soc/pcnt_struct.h:170:3: note:
'typedef volatile struct<anonymous> pcnt_dev_t' does not refer to the unqualified type, so it is not used for linkage
} pcnt_dev_t;
^
*** [.pioenvs\lolin32\src\Interrupt.ino.o] Error 1

What do you think about it ? Any ideas ?

Thanks,
Ondrej

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: Definition "extern pcnt_dev_t PCNT" + ISR

Postby ESP_Sprite » Sat Sep 02, 2017 2:59 am

Do you happen to know which version of ESP-IDF you are running?

ESP_igrr
Posts: 2067
Joined: Tue Dec 01, 2015 8:37 am

Re: Definition "extern pcnt_dev_t PCNT" + ISR

Postby ESP_igrr » Sat Sep 02, 2017 3:09 pm

Placing #include "soc/pcnt_struct.h" within extern "C" { ... } block should fix the issue. We are adding header guards for all components, so in the long run this workaround will not be needed.

onpa_esp32
Posts: 8
Joined: Tue Aug 29, 2017 7:41 am

Re: Definition "extern pcnt_dev_t PCNT" + ISR

Postby onpa_esp32 » Mon Sep 04, 2017 1:29 pm

Thanks. It helped.

Code: Select all

extern "C" {
  #include "soc/pcnt_struct.h"
}
#include "driver/pcnt.h"
solved the issue and Pulse counter is working now.

Code: Select all

/* interrupt function for PCNT */
void IRAM_ATTR pcnt_example_intr_handler(void* arg) {
  uint32_t intr_status;
  intr_status = PCNT.int_st.val;
  int i;

  state = !state;
  digitalWrite(ledPin, state);

  /* smažeme příznak přerušení */
  for(i = 0; i < PCNT_UNIT_MAX; i++) {
    if(intr_status & (BIT(i))) {
      PCNT.int_clr.val = BIT(i);
    }
  }
}
Just for info, inside ISR is necessary clear Interrupt Flag - "PCNT.int_st.val" ? Probably yes, without mentioned code inside ISR is micro frozen...
I saw example with calling "attachInterrupt" function, ISR function in this case doesn't use clearing flag mechanism...

Ondrej

filo_gr
Posts: 109
Joined: Wed Jul 28, 2021 12:25 pm
Location: Italy

Re: Definition "extern pcnt_dev_t PCNT" + ISR

Postby filo_gr » Fri Jan 06, 2023 6:01 pm

ESP_igrr wrote:
Sat Sep 02, 2017 3:09 pm
Placing #include "soc/pcnt_struct.h" within extern "C" { ... } block should fix the issue. We are adding header guards for all components, so in the long run this workaround will not be needed.
This helped me too, without extern "C". ESP-IDF v4.4.0 :D
Filippo

Akuji!
Posts: 1
Joined: Sun Feb 04, 2024 2:13 am

Re: Definition "extern pcnt_dev_t PCNT" + ISR

Postby Akuji! » Sun Feb 04, 2024 2:18 am

ESP_igrr wrote:
Sat Sep 02, 2017 3:09 pm
Placing #include "soc/pcnt_struct.h" within extern "C" { ... } block should fix the issue. We are adding header guards for all components, so in the long run this workaround will not be needed.
Thanks! Now I'm getting an undefined error with "PCNT_STATUS_THRES0_M" and "PCNT_STATUS_THRES1_M" variables :shock:
Is there any other file I should import?
Thanks!

Who is online

Users browsing this forum: gfvalvo and 66 guests