Blocking Functions

or calls? I was wondering if there is a writeup on what blocks interrupts.

This function seems to block HW interrupt0:

void sweep() {
  Serial.println(" Sweep Mode");
  tuning_word_F1 = (F1 * 0x100000000LL)/124999100L;
  tuning_word_F2 = (F2 * 0x100000000LL)/124999100L;
  tuning_word_fStep = (fStep * 0x100000000LL)/124999100L;
  while (mode == 2) {
    long timeSweepStart = micros();
    for (int i = 0; i < 10000; i++) {
    long timeStepStart = micros();
    while (tuning_word <= tuning_word_F2) {
      long timenow = micros();
      if ((timenow - timeStepStart) >= timeDwell) {
        timeStepStart = timenow;
        SetFrequency(tuning_word);
        tuning_word = tuning_word + tuning_word_fStep;
      }
    }
    tuning_word = tuning_word_F1;
    }
    long timeSweepStop = micros();
    long timeSweep = timeSweepStop - timeSweepStart;
    if (timeSweep < 1000) {
      Serial.print(timeSweep);
      Serial.println(" us");
    }
    else if (timeSweep < 1000000) {
      Serial.print(double(timeSweep)/1000);
      Serial.println(" ms");
    }
    else if (timeSweep >= 1000000) {
      Serial.print(double(timeSweep)/1000000);
      Serial.println(" s");
    }
  }
}

You might want to bookmark some pages and keep a tab open:

http://arduino.cc/en/Reference/HomePage

http://www.nongnu.org/avr-libc/user-manual/modules.html

As for your question, look for the word Interrupts on that first link, Arduino Reference

There is the #inclide <avr/atomic.h> header.

I have also made an implementation using global interrupts ( link in my signature ), Once I pretty up my site I’ll have a new version dealing with specific interrupts, not just global.

However there is nothing in your code that does anything to the interrupts.

Mark

C2: or calls? I was wondering if there is a writeup on what blocks interrupts.

This function seems to block HW interrupt0:

How do you know? Nothing you posted uses interrupts (except serial writing, indirectly).

Sorry, I have an interrupt attached to a button and sweep() does not exit until the serial prints are complete. The function takes minutes to complete and one press is all that is needed to wait for all the sweeps to complete and then the serial prints before exiting. Also not obvious, the SetFrequency(tuning_word); uses several spi.transfer commands.

Since I can break out of the function, it seems the while loops do not block. I thought the spi or serial transfer might, but then I don’t know why all of the serial prints happen without being interrupted before or between writes?

Read the sticky at the top of the form and the post all your code!.

Mark

I guess my question is more generic about interrupt blocking.

I think what’s happening is that the interrupt exits back to the program where it left off.

In the example below, mode 2 takes a long time to run, and will process to the end before the interrupt seems to do anything. I wanted to break out at any instance.

#define BUTTON 3 //interrupt 1
volatile int mode = 1;
long debouncing_time = 30000; //debouncing time in microseconds
volatile unsigned long last_micros = 0;

void setup() 
{
  Serial.begin(115200);
  pinMode(BUTTON, INPUT_PULLUP);
  attachInterrupt(1, debounce, RISING);
}

void loop() 
{
  if (mode == 0) {
    Serial.println("Mode = 0");
    delay(9000);
  }
  if (mode == 1) {
    Serial.println("Mode = 1");
  }
  if (mode == 2) {
    Serial.println("Mode = 2");
    unsigned long n = 0;
    while (mode == 2) {
      for (int i = 0; i < 100; i++) {
        long timeStepStart = micros();
        while (n <= 1000) {
          n++;
          Serial.println(n);
        }
        n = 0;
        Serial.println("do again");
        Serial.println(i);
      }
      Serial.println("Mode = 2");
    }
  }
}

void debounce() 
{
  if((long)(micros() - last_micros) >= debouncing_time) {
    last_micros = micros();
    mode = mode + 1;
    if (mode > 2) {
      mode = 0;
    }
  }
}

Likewise with mode 0, the interrupt does not break the delay function. I know it was written somewhere, maybe just in a post here some time ago, or in some other article.

I think what's happening is that the interrupt exits back to the program where it left off.

That's what they're supposed to do.

I don't imagine those delays are helping your responsiveness.

 if (mode == 0) {
    Serial.println("Mode = 0");
    delay(9000);
  }

If you get an interrupt one second into that delay, you still have to wait 8 seconds. Rework without using delay.

http://www.gammon.com.au/blink

So I guess the only way out is to check mode more often...

The rules for using an interrupt function are that:

1) It takes as little time as possible to complete - microseconds is good. Its job is to handle the immediate work required to satisfy the hardware, and pass on to the main program.

2) It communicates with the rest of the program only via global variables, these variables are declared volatile.

3) The main program may have to inhibit interrupt handling briefly (a couple of microseconds) to read or write a consistent set of these volatile variables (if more than one byte). Otherwise the values seen by the main program may be "trampled" by the interrupt routine mid-way through access. The main program may also have to inhibit interrupts briefly to interact with the same hardware (such as an SPI request).

Basically the ISR only has access to the relevant variables and the hardware, knows nothing else about the state of the main program.