-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spurious Interrupts #1250
Comments
Found IT
I was doing something Wrong, I looked through the esp-idf/esp_intr_alloc.h and found some configuration flags: /** @brief Interrupt allocation flags
*
* These flags can be used to specify which interrupt qualities the
* code calling esp_intr_alloc* needs.
*
*/
//Keep the LEVELx values as they are here; they match up with (1<<level)
#define ESP_INTR_FLAG_LEVEL1 (1<<1) ///< Accept a Level 1 interrupt vector (lowest priority)
#define ESP_INTR_FLAG_LEVEL2 (1<<2) ///< Accept a Level 2 interrupt vector
#define ESP_INTR_FLAG_LEVEL3 (1<<3) ///< Accept a Level 3 interrupt vector
#define ESP_INTR_FLAG_LEVEL4 (1<<4) ///< Accept a Level 4 interrupt vector
#define ESP_INTR_FLAG_LEVEL5 (1<<5) ///< Accept a Level 5 interrupt vector
#define ESP_INTR_FLAG_LEVEL6 (1<<6) ///< Accept a Level 6 interrupt vector
#define ESP_INTR_FLAG_NMI (1<<7) ///< Accept a Level 7 interrupt vector (highest priority)
#define ESP_INTR_FLAG_SHARED (1<<8) ///< Interrupt can be shared between ISRs
#define ESP_INTR_FLAG_EDGE (1<<9) ///< Edge-triggered interrupt
#define ESP_INTR_FLAG_IRAM (1<<10) ///< ISR can be called if cache is disabled
#define ESP_INTR_FLAG_INTRDISABLED (1<<11) ///< Return with this interrupt disabled
#define ESP_INTR_FLAG_LOWMED (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3) ///< Low and medium prio interrupts. These can be handled in C.
#define ESP_INTR_FLAG_HIGH (ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6|ESP_INTR_FLAG_NMI) ///< High level interrupts. Need to be handled in assembly.
#define ESP_INTR_FLAG_LEVELMASK (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3| \
ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6| \
ESP_INTR_FLAG_NMI) ///< Mask for all level flags I changed the interrupt attached code to: uint32_t flags = ESP_INTR_FLAG_EDGE |//< Edge-triggered interrupt
ESP_INTR_FLAG_IRAM; //< ISR can be called if cache is disabled
switch(i2c->num){
case 0:
ret = esp_intr_alloc(ETS_I2C_EXT0_INTR_SOURCE, flags, &i2c_isr_handler_default, i2c, &i2c->intr_handle);
break;
case 1:
ret = esp_intr_alloc(ETS_I2C_EXT1_INTR_SOURCE, flags, &i2c_isr_handler_default, i2c, &i2c->intr_handle);
break;
default :;
} No more Spurious interrupts, We need to check the @me-no-dev do you know if I should be using more of these values? Like Chuck. |
@me-no-dev Should I try to code my ISR to work in a 'Shared' interrupt mode using: /**
* @brief Allocate an interrupt with the given parameters.
*
*
* This essentially does the same as esp_intr_alloc, but allows specifying a register and mask
* combo. For shared interrupts, the handler is only called if a read from the specified
* register, ANDed with the mask, returns non-zero. By passing an interrupt status register
* address and a fitting mask, this can be used to accelerate interrupt handling in the case
* a shared interrupt is triggered; by checking the interrupt statuses first, the code can
* decide which ISRs can be skipped
*
* @param source The interrupt source. One of the ETS_*_INTR_SOURCE interrupt mux
* sources, as defined in soc/soc.h, or one of the internal
* ETS_INTERNAL_*_INTR_SOURCE sources as defined in this header.
* @param flags An ORred mask of the ESP_INTR_FLAG_* defines. These restrict the
* choice of interrupts that this routine can choose from. If this value
* is 0, it will default to allocating a non-shared interrupt of level
* 1, 2 or 3. If this is ESP_INTR_FLAG_SHARED, it will allocate a shared
* interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return
* from this function with the interrupt disabled.
* @param intrstatusreg The address of an interrupt status register
* @param intrstatusmask A mask. If a read of address intrstatusreg has any of the bits
* that are 1 in the mask set, the ISR will be called. If not, it will be
* skipped.
* @param handler The interrupt handler. Must be NULL when an interrupt of level >3
* is requested, because these types of interrupts aren't C-callable.
* @param arg Optional argument for passed to the interrupt handler
* @param ret_handle Pointer to an intr_handle_t to store a handle that can later be
* used to request details or free the interrupt. Can be NULL if no handle
* is required.
*
* @return ESP_ERR_INVALID_ARG if the combination of arguments is invalid.
* ESP_ERR_NOT_FOUND No free interrupt found with the specified flags
* ESP_OK otherwise
*/
esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusreg, uint32_t intrstatusmask, intr_handler_t handler, void *arg, intr_handle_t *ret_handle); uint32_t flags = ESP_INTR_FLAG_SHARED | //< Interrupt can be shared between ISRs
ESP_INTR_FLAG_EDGE | //< Edge-triggered interrupt
ESP_INTR_FLAG_IRAM | //< ISR can be called if cache is disabled
ESP_INTR_FLAG_LOWMED; //< Low and medium prio interrupts. These can be handled in C.
ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT0_INTR_SOURCE, flags, &i2c->dev->int_status.val, 0x1FFF, &i2c_isr_handler_default,i2c, &i2c->intr_handle); I don't know how scarce a resource these interrupts are, can you give me your perspective? Chuck. EDIT: 04/16/2018 |
yesterday I tryed to understand the attachInterrupt() funktion and there were serveral things I did not understand:
Why check ´if(!Interrupt_initialized)´ when it is set in the line above or is it because a `static bool' only gets initialised at the beginning?
the only used FLAG is And the most important part. Where do I find the code that actually checkes the pin state and determents the trigger reason? |
Yes, the static part means the variable only gets defined/initialised on first execution so that code runs once on first execution and then set the flag so not run again. Tim |
i have check using esp-idf gpio code that is working fine for positive edge trigger....but not working in arduino............ |
negedge is working fine for esp-idf but not working in arduino core in arduino core just working for change |
This may not help you. |
we are designing pulse counter which change rate from 240 MHZ to 2 MHZ to save energy......i was using PCNT but debouncing is limited so it is catching noise i need isr on falling so i could perform some filtering but with change i am unable to do so,,,,i am unable to understand that esp-idf working fine it means issue is there in arduino core...is there any option to directly configure gpios using esp-idf while using arduino as we did for PCNT |
have you tried to use "deeper" methodes?
I guess you can write your own interrupt routine. maybe even outside the Arduino "loop", as a new task. |
interesting did u tried that? |
i tried this approach but there are compilation errors void setup()
} |
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type);
exit status 1 |
I only had limited succsess, and in the end it didn't work because I never got triggering on LOW to work. |
YES PROBLEM SOLVED |
well well well. please share your solution, so me and others can learn from it. |
#include "driver/gpio.h" #define GPIO_OUTPUT_IO_0 18 static xQueueHandle gpio_evt_queue = NULL; static void IRAM_ATTR gpio_isr_handler(void* arg) } void setup() Serial.begin(115200);
} } |
pin 4 and 5 configured for positive edge interrupt...Arduino IDE |
Hardware:
Board: ?WeMos BlueTooth with Battery?
Core Installation/update date: ?09MAR2018
IDE name: ?Arduino IDE 1.8.5
Flash Frequency: ?80Mhz?
Upload Speed: ?921600?
Description:
I am working on SLAVE mode I2C, my interrupt service routine (ISR) is receiving interrupts without any interrupt cause.
The following is a dump of a capture buffer that lists all arriving interrupts, the CCOUNT (cycle Count) when they were dispatched, and the pending hardware interrupt state.
The interesting columns are:
As you can see each interrupt is processed, and the ISR exits, immediately the ISR is re-entered without any interrupt source. I have coded around it by
if(i2c->dev->int_status.val==0) return;
, but there is something I am not understanding, or doing wrong. What is generating this wasted interrupt cycle?There are multiple open issues around interrupts. #1111, #1229 I am wondering all of these have the same basis?
Am I not clearing the interrupt correctly? I use
i2c->dev->int_clr.val = activeInterrupt;
, to clear the interrupt status flag after I have responded to the underlying interrupt cause, so I only clear the interrupts I receive. I am not 'ignoring' any interrupt by just clearing the flag.Chuck
The text was updated successfully, but these errors were encountered: