Skip to content

Long delay in first call to interrupt #797

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

Closed
plerup opened this issue Sep 16, 2015 · 7 comments
Closed

Long delay in first call to interrupt #797

plerup opened this issue Sep 16, 2015 · 7 comments
Milestone

Comments

@plerup
Copy link
Contributor

plerup commented Sep 16, 2015

Hi,

I'm using the standard Arduino routines for setting up an interrupt for a GPIO pin

pinMode(RX_PIN, INPUT);
attachInterrupt(RX_PIN, rxInt, FALLING);

The problem I get is that the very first call to the interrupt routine (after system reset) has a delay of > 20 uS from the GPIO pin flank to the actual call. Any subsequent calls just have a delay of 4 uS.

If I use the SDK routines like this:

ETS_GPIO_INTR_ATTACH(intr, 0);
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(RX_PIN));
gpio_pin_intr_state_set(GPIO_ID_PIN(RX_PIN), GPIO_PIN_INTR_NEGEDGE);

then I don't get this behavior.

Any ideas why this is so?

Thanks
/Peter

@Links2004
Copy link
Collaborator

try to change the
void interrupt_handler(void *arg) {
to
void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
in
core_esp8266_wiring_digital.c

@igrr
Copy link
Member

igrr commented Sep 16, 2015

I think this method won't work because linker directives have higher
precedence over compiler attributes. We would have to move interrupt
handler (and other routines currently marked with ICACHE_RAM_ATTR) to a
separate .c file which will not be subject to the rule defined in linker
script.

We also need to move section renaming to a later stage, otherwise stuff
like -gc-sections doesn't work. Have to think about this a bit...

On Wed, Sep 16, 2015, 23:27 Markus [email protected] wrote:

try to change the
void interrupt_handler(void *arg) {
to
void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
in
core_esp8266_wiring_digital.c


Reply to this email directly or view it on GitHub
#797 (comment).

@plerup
Copy link
Contributor Author

plerup commented Sep 17, 2015

Here is an example that can be used to show this phenomenon. Just shortcut pin 12 and 14

My result is like this:

Interrupt test started
Delay = 23
Delay = 5
Delay = 4
Delay = 4
Delay = 5
Delay = 4

#define OUT 12
#define IN 14
unsigned long intrTime = 0;
void intr () {
  intrTime = micros();
}
void setup() {
  Serial.begin(115200);
  pinMode(OUT, OUTPUT);
  digitalWrite(OUT, HIGH);
  pinMode(IN, INPUT);
  attachInterrupt(IN, intr, FALLING);
  Serial.println("Interrupt test started");
}
void loop() {
  unsigned long start = micros();
  digitalWrite(OUT, LOW);
  delay(1000);
  Serial.print("Delay = ");
  Serial.println(intrTime-start);
  digitalWrite(OUT, HIGH);
  delay(2000);
}

@igrr
Copy link
Member

igrr commented Sep 17, 2015

Thank you for the example, the reason why this happens is totally clear.
The question now is how to improve our linker rules to meet all of the
following:

  • Place code into flash by default
  • Allow -ffunction-sections and -fdata-sections to generate separate
    sections for each symbol so that -gc-sections will work
  • Make it possible to mark functions to be placed into RAM.

As I see it, doing all three at the same time is tricky... Perhaps we need
to relax these criteria a bit, i.e. ignore garbage collection requirement
for functions placed into RAM.
Comments and ideas are totally welcome here.

P.S. of course there is a simple workaround for this particular case
(mentioned in my previous reply). But since this isn't a blocker, I would
prefer to fix this by solving the underlying issue, not it's manifestation.

On Thu, Sep 17, 2015, 20:56 Peter Lerup [email protected] wrote:

Here is an example that can be used to show this phenomenon. Just shortcut
pin 12 and 14

My result is like this:

Interrupt test started
Delay = 23
Delay = 5
Delay = 4
Delay = 4
Delay = 5
Delay = 4

#define OUT 12
#define IN 14
unsigned long intrTime = 0;
void intr () {
intrTime = micros();
}
void setup() {
Serial.begin(115200);
pinMode(OUT, OUTPUT);
digitalWrite(OUT, HIGH);
pinMode(IN, INPUT);
attachInterrupt(IN, intr, FALLING);
Serial.println("Interrupt test started");
}
void loop() {
unsigned long start = micros();
digitalWrite(OUT, LOW);
delay(1000);
Serial.print("Delay = ");
Serial.println(intrTime-start);
digitalWrite(OUT, HIGH);
delay(2000);
}


Reply to this email directly or view it on GitHub
#797 (comment).

@plerup
Copy link
Contributor Author

plerup commented Sep 17, 2015

I'm confident that you will come up with a good solution. Thank you so much for your fantastic work on this project!

The reason for my problem is that I'm implementing a SoftwareSerial class and got problem with the very first byte when running at 115200 baud due to this.

@alecapu
Copy link

alecapu commented Sep 28, 2015

Hi,
I've a very strange interrupt problem me too. I've a sample I2S application that use TX and RX I2S channels in loopback. If I compile the code with the ESP SDK every things work fine. If I try to migrate it to Arduino the DMA interrupt is not called.... some one with more experience can help me?

@me-no-dev
Copy link
Collaborator

@alecapu you have code for I2S-RX? Can you share that with us so we can add it to the core?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants