The title speaks for itself !
Is it possible to call a routine/function from an ISR?
Note: I understand that the code should stay minimal, but in my case, I want a couple of ISR's to run the same code.
The title speaks for itself !
Is it possible to call a routine/function from an ISR?
Note: I understand that the code should stay minimal, but in my case, I want a couple of ISR's to run the same code.
You could always test
But, yes, there is no reason that would not work (at least none that I'm aware of) :]
I tried :-X and missed thus my question :-/
I should have added that the code belongs to a library. The compiler says unrecognized function talking about the called routine/function, while everything looks ok (99.99% sure)
On the other hand: after (spending an hour) searching, I found an alternative to my question: the ISR_ALIASOF flag!
Anyway, I am interested in the answer to the original question... Thanks for helping
You should not call an ISR routine from code, but rather use the ISR_ALIASOF macro to specify a common handler for two or more ISR's.
The alternative would be to call a third routine from within the two ISR's that execute the common code.
I should have added that the code belongs to a library. The compiler says unrecognized function talking about the called routine/function, while everything looks ok (99.99% sure)
Must be a bug in the compiler, then.
Why don't you post the code before assuming that it is the compiler that is wrong. Because the compiler is never wrong.
Did I assmume anything related to the compiler? I am just asking... Sorry if my prose was not clear enough, english is not my mother langage.
I did not post the real code which is huge. As an exemple, I wished to use a command readState() function within the next ISR instead of startState and stopState .
ISR(PCINT0_vect) {
// Interrupt service request for external interrupt
// Interpret switches position
static uint8_t prevState = 0x03;
// Get current state
uint8_t startState = ((((PIN(*_encPort) >> _swA) & 0x01) << 2) | (((PIN(*_encPort) >> _swB) & 0x01) << 1) | ((PIN(*_encPort) >> _swPb) & 0x01));
// Simple debouncing. 1 nop = 62.5 ns, 1600 nops approx 100 us
for (int i=0; i < 1600; i++)
asm volatile ("NOP");
// Get current state
uint8_t stopState = ((((PIN(*_encPort) >> _swA) & 0x01) << 2) | (((PIN(*_encPort) >> _swB) & 0x01) << 1) | ((PIN(*_encPort) >> _swPb) & 0x01));
// Check if the previous state was stable and different from the previous one
if ((startState == stopState) && (stopState != prevState)) {
_buttonDown = (~startState & 0x01); // Update button state
if ((startState >> 1) == 0x03) { // If in idle state
// Decode steps pattern
if (patternBuffer == patternCW)
_counts++;
if (patternBuffer == patternCCW)
_counts--;
patternBuffer = 0x00; // reset buffer
}
else {
// Append state to the buffer
patternBuffer <<= 2;
patternBuffer |= (startState >> 1) ;
}
prevState = stopState; // Record state for next change
}
}
Anyway, my major concern was for the whole content of the ISR, and yes, the ISR_ALIASOF flag solves the problem at the price of two lines of code !
// Use PCINT0_vect for PCINT1_vect and PCINT2_vect
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
Did I assmume anything related to the compiler?
You said:
The compiler says unrecognized function...while everything looks ok (99.99% sure)
If everything looks OK, but the compiler says there is a problem, it's best to assume that the compiler is right.
for (int i=0; i < 1600; i++)
asm volatile ("NOP");
A fancy delay in an ISR. Nice.
So, this is the code you are using. Where is the code you want to call? What error message(s) do you get when you try to call the function?
We are getting far from my original question which is:
Is it possible to call a sub routine from an ISR? I am just asking.
On the other hand, I understand that the good forum pratices recommand to avoid multiple threads from the same topic. So that I will create new topics for the new questions from some of you. I will try to solve the misunderstandings by MP. Link here http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282810975/0#0
// Simple debouncing. 1 nop = 62.5 ns, 1600 nops approx 100 us
for (int i=0; i < 1600; i++)
asm volatile ("NOP");
That loop will take 100 us only if it is fully unwinded, i.e. is implemented as 1600 consecutive nops. I haven't checked the assembler, but surely there will be adjustments of "i" and branches involved.
Thanks drhex. I moved this specification question to a new topic http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282810975/0#0 Would you contribute to it.
End of game. The problem is under investigation in some other places where it has been reproduced aknowledged and ranked as strange.
So far the answer is:
Yes it is possible to call a sub function from an ISR. Bit it has restrictions (We will cover that in some other place). And it is not recommended to do so because it lengthens the execution of the ISR.