How to use gpio_isr_register?
How to use gpio_isr_register?
Looking at the driver/gpio.h header file, I find a reference to gpio_isr_register() as a method for registering what appears to be an interrupt handler. Unfortunately, I'm not understanding how to properly use it. The first parameter to it is something called a "gpio_intr_num" and I'm not understanding what the comments in the header say about it. Has anyone looked into this area yet? I think I am sensing that there is also an underlying ROM based GPIO implementation but most of these APIs say not to use in the SDK.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: How to use gpio_isr_register?
Read technical reference manual about interrupt matrix. Interrupt matrix maps peripheral interrupts (table 6) to CPU interrupts (table 7). CPU interrupts have one interrupt handler function, so you have to pick and choose which sources will trigger the same interrupt number and thus share a handler function. Also you have to consider priority levels, shown in table 7. In the case of gpio interrupts, there is only one signal into the interrupt matrix so they will all share the same interrupt handler and you only have to set it up once.
I tried the example in gpio.h with gpio0 and get the interrupt messages over uart when the button on devkitc is pressed.
I tried the example in gpio.h with gpio0 and get the interrupt messages over uart when the button on devkitc is pressed.
Re: How to use gpio_isr_register?
where is the code?WiFive wrote:
I tried the example in gpio.h with gpio0 and get the interrupt messages over uart when the button on devkitc is pressed.
@Neil
example you connect a PIR to the GPIO17
you build an alarm
https://www.mpja.com/download/31227sc.pdf
The PIR i linked has 3.3 / 0 TTL
with 5 V supply
because Nano32 has 5.0 V output too,
i connect 5 V to Power
ground to ground
TTL to GPIO 17
( bevore i test with push button )
here is a example with PIR and the Nano32 form MakerAsia & GravitechThai
an here the code for you.
if you use in your book
please named it
credit: MakerAsia
thank you
Code: Select all
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
//
#define INPUT_GPIO 17
// #define INPUT_GPIO_DOORBUTTON 18
// #define INPUT_GPIO_ALARMBUTTON 19
#define TAG 3
void gpioCallback (void* arg);
/******************************************************************************
* FunctionName : hello_task
* Description :
* Parameters : void* pvParameter
* Returns :
*******************************************************************************/
void hello_task(void* pvParameter)
{
/* Calc */
printf("Hello, how are you?!\n");
for (int i = 10; i >= 0; i--) {
printf("Restarting in %d seconds...\n", i);
vTaskDelay(1000 / portTICK_RATE_MS);
}
printf("Restarting now.\n");
fflush(stdout);
system_restart();
}
/******************************************************************************
* FunctionName : main_task
* Description :
* Parameters : void* pvParameter
* Returns : void
*******************************************************************************/
void main_task(void* pvParameter)
{
/* Calc */
/* Configure the IOMUX register for pad BLINK_GPIO (some pads are
muxed to GPIO on reset already, but some default to other
functions and need to be switched to GPIO. Consult the
Technical Reference for a list of pads and their default
functions.)
*/
gpio_pad_select_gpio(INPUT_GPIO);
/* Set the GPIO as a input */
gpio_set_direction(INPUT_GPIO, GPIO_MODE_INPUT);
/* Set the GPIO pull */
gpio_set_pull_mode(INPUT_GPIO, GPIO_PULLUP_ONLY);
// gpio_set_intr_type(INPUT_GPIO, GPIO_INTR_NEGEDGE);
// gpio_set_intr_type(INPUT_GPIO, GPIO_INTR_ANYEDGE);
gpio_set_intr_type(INPUT_GPIO, GPIO_INTR_ANYEDGE);
gpio_intr_enable(INPUT_GPIO);
// Intterrupt number see below
gpio_isr_register(INPUT_GPIO, gpioCallback, (void *)TAG); // 17
while(1) {
// if you need..
// printf( "Loop...\n" );
// vTaskDelay(1000 / portTICK_RATE_MS);
}
}
/******************************************************************************
* FunctionName : gpioCallback
* Description :
* Parameters : void* arg
* Returns :
*******************************************************************************/
void gpioCallback(void* arg)
{
/* Calc */
uint32_t gpio_num = 0;
uint32_t gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG); //read status to get interrupt status for GPIO0-31
uint32_t gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);//read status1 to get interrupt status for GPIO32-39
SET_PERI_REG_MASK(GPIO_STATUS_W1TC_REG, gpio_intr_status); //Clear intr for gpio0-gpio31
SET_PERI_REG_MASK(GPIO_STATUS1_W1TC_REG, gpio_intr_status_h); //Clear intr for gpio32-39
do {
if(gpio_num < 32) {
if(gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio31
ets_printf("1 Intr GPIO%d ,val: %d\n",gpio_num,gpio_get_level(gpio_num));
//This is an isr handler, you should post an event to process it in RTOS queue.
/ * test your self......
switch (gpio_intr_status & BIT(gpio_num)) {
case 17: ets_print("GPIO 17 request\n"); break;
case 18: ets_print("GPIO 18 request : task2 call\n");
xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
break;
}
* /
}
// }
} else {
if(gpio_intr_status_h & BIT(gpio_num - 32)) {
ets_printf("2 Intr GPIO%d, val : %d\n",gpio_num,gpio_get_level(gpio_num));
//This is an isr handler, you should post an event to process it in RTOS queue.
}
}
} while(++gpio_num < GPIO_PIN_COUNT);
/* push_status = ; */
}
/******************************************************************************
* * * * * * * *: main of ESP32
* FunctionName : app_main
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void app_main()
{
/* Calc */
nvs_flash_init();
system_init();
// xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
xTaskCreate(&main_task, "main_task", 2048, NULL, 5, NULL);
}
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
Re: How to use gpio_isr_register?
Thanks @rudi for the example. Just a note of caution,
I haven't triple checked yet but I think the example will only work for certain GPIO pins.
I think the first argument of gpio_isr_register lists the interrupt number -- and from the listing from soc.h, some of them are already used.
In the example interrupt number 17 was the same as the GPIO pin so it worked.
Hope that clarifies things for @kolban?
I haven't triple checked yet but I think the example will only work for certain GPIO pins.
I think the first argument of gpio_isr_register lists the interrupt number -- and from the listing from soc.h, some of them are already used.
In the example interrupt number 17 was the same as the GPIO pin so it worked.
Hope that clarifies things for @kolban?
Code: Select all
//interrupt cpu using table, Please see the core-isa.h
260 /*************************************************************************************************************
261 * Intr num Level Type PRO CPU usage APP CPU uasge
262 * 0 1 extern level WMAC Reserved
263 * 1 1 extern level BT/BLE Host VHCI Reserved
264 * 2 1 extern level FROM_CPU FROM_CPU
265 * 3 1 extern level TG0_WDT Reserved
266 * 4 1 extern level WBB
267 * 5 1 extern level BT Controller
268 * 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1)
269 * 7 1 software Reserved Reserved
270 * 8 1 extern level BLE Controller
271 * 9 1 extern level
272 * 10 1 extern edge Internal Timer
273 * 11 3 profiling
274 * 12 1 extern level
275 * 13 1 extern level
276 * 14 7 nmi Reserved Reserved
277 * 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3)
278 * 16 5 timer
279 * 17 1 extern level
280 * 18 1 extern level
281 * 19 2 extern level
282 * 20 2 extern level
283 * 21 2 extern level
284 * 22 3 extern edge
285 * 23 3 extern level
286 * 24 4 extern level
287 * 25 4 extern level Reserved Reserved
288 * 26 5 extern level Reserved Reserved
289 * 27 3 extern level Reserved Reserved
290 * 28 4 extern edge
291 * 29 3 software Reserved Reserved
292 * 30 4 extern edge Reserved Reserved
293 * 31 5 extern level Reserved Reserved
294 *************************************************************************************************************
295 */
-
- Posts: 9764
- Joined: Thu Nov 26, 2015 4:08 am
Re: How to use gpio_isr_register?
@jimbob: The interrupt number has nothing to do with the GPIO number. The GPIO mux basically allows you to pick a random interrupt for a peripheral; any that are marked as free in the table you mentioned will work.
Re: How to use gpio_isr_register?
no hurry!
hi
i get a small panic'ed
after isr fired for gpio18..
what is mean with "/queue.c:603 (xQueueGenericSend)- assert failed!"
thanks
best wishes
rudi
hi
i get a small panic'ed
after isr fired for gpio18..
what is mean with "/queue.c:603 (xQueueGenericSend)- assert failed!"
Code: Select all
1 Intr GPIO18 ,val: 0<\r><\n>
GPIO 18 request : restart call<\r><\n>
c:/sdk32/esp-idf/components/freertos/./queue.c:603 (xQueueGenericSend)- assert failed!<\r><\n>
Guru Meditation Error: Core 0 panic'ed.<\r><\n>
Register dump:<\r><\n>
PC : Guru Meditation Error of type LoadProhibited occurred on core 0. Exception was unhandled.<\r><\n>
Register dump:<\r><\n>
PC : 40083456 PS : 00060033 A0 : 80083679 A1 : 3ffb3180 <\r><\n>
A2 : 00000000 A3 : 00000002 A4 : 00000000 A5 : 00000000 <\r><\n>
A6 : 3f401044 A7 : 3ff4001c A8 : 0000007d A9 : 3ff4001c <\r><\n>
A10 : 3ff4001c A11 : 3f4002d0 A12 : 00000000 A13 : 3ffb31e0 <\r><\n>
A14 : 00000000 A15 : 3f401158 SAR : 00000017 EXCCAUSE: 0000001c <\r><\n>
EXCVADDR: 00000004 LBEG : 4000c2e0 LEND : 4000c2f6 LCOUNT : 00000000 <\r><\n>
Rebooting...<\r><\n>
ets Jun 8 2016 00:22:57<\r><\n>
Code: Select all
/******************************************************************************
*
* Espressif IoT Development Framework with the ESP32
*
* ESP-IDF -
* the new Espressif IoT Development Framework with ESP32 from espressif
* github : https://github.com/espressif/esp-idf
*
*
*******************************************************************************/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#define PIR_GPIO 17
#define BTN_GPIO 18
#define TAG 3
void gpioCallback (void* arg);
/******************************************************************************
* FunctionName : main_task
* Description :
* Parameters : void* pvParameter
* Returns : void
*******************************************************************************/
void main_task(void* pvParameter)
{
/* Configure the IOMUX register for pad BLINK_GPIO (some pads are
muxed to GPIO on reset already, but some default to other
functions and need to be switched to GPIO. Consult the
Technical Reference for a list of pads and their default
functions.)
*/
gpio_pad_select_gpio(PIR_GPIO);
gpio_pad_select_gpio(BTN_GPIO);
/* Set the GPIO as a input */
gpio_set_direction(PIR_GPIO, GPIO_MODE_INPUT);
gpio_set_direction(BTN_GPIO, GPIO_MODE_INPUT);
/* Set the GPIO pull */
gpio_set_pull_mode(PIR_GPIO, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(BTN_GPIO, GPIO_PULLUP_ONLY);
// gpio_set_intr_type(INPUT_GPIO, GPIO_INTR_NEGEDGE);
gpio_set_intr_type(PIR_GPIO, GPIO_INTR_ANYEDGE);
gpio_set_intr_type(BTN_GPIO, GPIO_INTR_NEGEDGE);
gpio_intr_enable(PIR_GPIO);
gpio_intr_enable(BTN_GPIO);
// Intterrupt number see below
gpio_isr_register(PIR_GPIO, gpioCallback, (void *)TAG); // 17
gpio_isr_register(BTN_GPIO, gpioCallback, (void *)TAG); // 18
while(1) {
// printf( "Loop...\n" );
// vTaskDelay(1000 / portTICK_RATE_MS);
}
}
/******************************************************************************
* FunctionName : gpioCallback
* Description :
* Parameters : void* arg
* Returns :
*******************************************************************************/
void gpioCallback(void* arg)
{
uint32_t gpio_num = 0;
uint32_t gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG); //read status to get interrupt status for GPIO0-31
uint32_t gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);//read status1 to get interrupt status for GPIO32-39
SET_PERI_REG_MASK(GPIO_STATUS_W1TC_REG, gpio_intr_status); //Clear intr for gpio0-gpio31
SET_PERI_REG_MASK(GPIO_STATUS1_W1TC_REG, gpio_intr_status_h); //Clear intr for gpio32-39
do {
if(gpio_num < 32) {
if(gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio31
ets_printf("1 Intr GPIO%d ,val: %d\n",gpio_num,gpio_get_level(gpio_num));
//This is an isr handler, you should post an event to process it in RTOS queue.
switch (gpio_num) {
case 17: ets_printf("GPIO 17 request\n"); break;
case 18: ets_printf("GPIO 18 request : restart call\n");
fflush(stdout);
system_restart();
break;
}
}
} else {
if(gpio_intr_status_h & BIT(gpio_num - 32)) {
ets_printf("2 Intr GPIO%d, val : %d\n",gpio_num,gpio_get_level(gpio_num));
//This is an isr handler, you should post an event to process it in RTOS queue.
}
}
} while(++gpio_num < GPIO_PIN_COUNT);
/* push_status = ; */
}
/******************************************************************************
* * * * * * * *: main of ESP32
* FunctionName : app_main
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void app_main()
{
nvs_flash_init();
system_init();
xTaskCreate(&main_task, "main_task", 2048, NULL, 5, NULL);
}
best wishes
rudi
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
Re: How to use gpio_isr_register?
Can you do that inside ISR?rudi ;-) wrote:Code: Select all
fflush(stdout);
Also don't do this:
Code: Select all
// Intterrupt number see below
gpio_isr_register(PIR_GPIO, gpioCallback, (void *)TAG); // 17
gpio_isr_register(BTN_GPIO, gpioCallback, (void *)TAG); // 18
Last edited by WiFive on Sat Oct 22, 2016 4:27 pm, edited 2 times in total.
Re: How to use gpio_isr_register?
That's why he is saying don't use it here:ESP_Sprite wrote:@jimbob: The interrupt number has nothing to do with the GPIO number. The GPIO mux basically allows you to pick a random interrupt for a peripheral; any that are marked as free in the table you mentioned will work.
Code: Select all
gpio_isr_register(INPUT_GPIO, gpioCallback, (void *)TAG); // 17
Re: How to use gpio_isr_register?
ups...WiFive wrote:Can you do that inside ISR?rudi ;-) wrote:Code: Select all
fflush(stdout);
how you register then second?WiFive wrote:
Also don't do this:
2nd one cancels the first one and you fell into jimbob's trapCode: Select all
// Intterrupt number see below gpio_isr_register(PIR_GPIO, gpioCallback, (void *)TAG); // 17 gpio_isr_register(BTN_GPIO, gpioCallback, (void *)TAG); // 18
need we for each a own Callback now?
i have this mean first think
Code: Select all
gpio_isr_register( (PIR_GPIO & BTN_GPIO ) , gpioCallback, (void *)TAG); // 17, 18
..where is the docu ...
edit: found this..
Code: Select all
esp_err_t gpio_isr_register (uint32_t gpio_intr_num, void(*fn)(void *), void *arg)
Last edited by rudi ;-) on Sat Oct 22, 2016 4:41 pm, edited 1 time in total.
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
Re: How to use gpio_isr_register?
No no. You do this many times:
And you do this only ONCE:
And then you do this inside gpioCallback:
Capisce?
Code: Select all
gpio_intr_enable(GPIO_NUM)
Code: Select all
gpio_isr_register(UNUSED_INTERRUPT_NUM, gpioCallback, (void *)TAG);
Code: Select all
do {
if(gpio_intr_status & BIT(gpio_num))
...
} while(++gpio_num < GPIO_PIN_COUNT);
Last edited by WiFive on Sat Oct 22, 2016 5:11 pm, edited 1 time in total.
Who is online
Users browsing this forum: No registered users and 135 guests