ESP32 ISR

BonaFid3
Posts: 2
Joined: Sun Apr 02, 2017 6:53 pm

ESP32 ISR

Postby BonaFid3 » Sun Apr 02, 2017 7:19 pm

Hello,

I need to use external interrupt with my ESP32. I set up the code like this:

Code: Select all

gpio_pad_select_gpio(GPIO_NUM_5);
gpio_set_direction(GPIO_NUM_5, static_cast<gpio_mode_t>(GPIO_MODE_INPUT));
gpio_set_pull_mode(GPIO_NUM_5, GPIO_PULLUP_ONLY);
gpio_set_intr_type(GPIO_NUM_5, GPIO_INTR_NEGEDGE);
gpio_intr_enable(GPIO_NUM_5);
gpio_isr_register(inthandler, nullptr, 0, 0);
I have a nice clean 75.2Hz signal which triggers the ISR.

Image

Code: Select all

void inthandler(void *arg){
	uint32_t gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG);
	uint32_t gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);
	SET_PERI_REG_MASK(GPIO_STATUS_W1TC_REG, gpio_intr_status);
	SET_PERI_REG_MASK(GPIO_STATUS1_W1TC_REG, gpio_intr_status_h);

	if((gpio_intr_status & BIT(GPIO_NUM_5)) == BIT(GPIO_NUM_5)) {

		BaseType_t xHigherPriorityTaskWoken, xResult;

		// xHigherPriorityTaskWoken must be initialised to pdFALSE.
		xHigherPriorityTaskWoken = pdFALSE;

		// Set bit 0 and bit 4 in xEventGroup.
		xResult = xEventGroupSetBitsFromISR(
				interrupt_event_group,	// The event group being updated.
							PIN_BIT,   // The bits being set.
							&xHigherPriorityTaskWoken );

		// Was the message posted successfully?
		if( xResult == pdPASS )
		{
			//ets_printf("xResult==pdPASS\n");
			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
			// switch should be requested.  The macro used is port specific and
			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
			// refer to the documentation page for the port being used.
			//portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
			//portEND_SWITCHING_ISR();
		} else {
			//ets_printf("xResult pdFAIL!\n");
		}
	}
}
In a separate task I'm checking the PIN_BIT in the interrupt_event_group like this:

Code: Select all

float elapsedSec() {
    timeval tv;
    gettimeofday(&tv, 0);
    return tv.tv_sec + tv.tv_usec * 1.0e-6f;
}

static void i2cTask(void *param) {
	while(1) {
		bool clearOnExit=true, waitForAllBits=true;
		xEventGroupWaitBits(interrupt_event_group, PIN_BIT, clearOnExit, waitForAllBits, portMAX_DELAY);
		float now = elapsedSec();
		float dt = now - past;
		past = now;
		std::cout << "dt: " << dt << std::endl;
	}
}
And I'm measuring strange delta time between interrupts like this:

Image

However, if I use xEventGroupSetBits instead of xEventGroupSetBitsFromISR in the ISR I get exactly 0.013s delta time in every cycle, but of course it crashes after a while.

Any idea how to solve this problem?

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

Re: ESP32 ISR

Postby ESP_Sprite » Mon Apr 03, 2017 3:42 am

Is there a reason you disabled the portYIELD_FROM_ISR stuff? Without it, if memory serves, your task that measures time will only be unblocked at the next FreeRTOS tick.

BonaFid3
Posts: 2
Joined: Sun Apr 02, 2017 6:53 pm

Re: ESP32 ISR

Postby BonaFid3 » Mon Apr 03, 2017 7:17 am

Ok, you are right. I have copied the code from event_groups.h and that says "portYIELD_FROM_ISR( xHigherPriorityTaskWoken );"
However the correct way to call portYIELD_FROM_ISR() without parameter.

So I have commented the portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) line because I got this error and I did not check the function declaration.
D:/projects/esp32/msys32/home/bonafid3/esp-idf/examples/get-started/blink/main/blink.cpp:368:4: error: 'portYIELD_FROM_ISR' was not declared in this scope
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
^
Silly me. Now it compiles, but I can try it later today.
Thank you for your help!

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: ESP32 ISR

Postby WiFive » Tue Apr 04, 2017 2:53 am


Who is online

Users browsing this forum: No registered users and 147 guests