Skip to content
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

PinChangeInterrupts and SoftwareSerial #419

Open
schmidtjr opened this issue Jul 9, 2021 · 1 comment
Open

PinChangeInterrupts and SoftwareSerial #419

schmidtjr opened this issue Jul 9, 2021 · 1 comment

Comments

@schmidtjr
Copy link

schmidtjr commented Jul 9, 2021

Why is SoftwareSerial defining ISR for all possible PinChangeInterrupt vectors? Even if not all of them are used, the ISR is registered and prevents others (e.g. other libs) from registering PinChangeInterrupts.

For example. If you use SoftwareSerial on Digital Ports 2 and 3 (Arduino Uno/Nano), it is not possible to specify a PinchangeInterrupt for pin A1. (e.g. by using PinChangeInterrupt library).

Reason is, that SoftwareSerial registers on ISR for all ports. Why? Since SoftwareSerial is some kind of system library, to me this behavior seems wrong.

Wouldn't at least something like the following code snippet be useful? (Would prevent users from including their own hacked SoftwareSerial.cpp, missing new updates...)

(originally lines 227-244 in SoftwareSerial.cpp)

#if defined(PCINT0_vect)
ISR(PCINT0_vect)
{
  SoftwareSerial::handle_interrupt();
}
#endif

#ifndef SOFTSERIAL_IGNORE_PCINT1
#if defined(PCINT1_vect)
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
#endif
#endif

#ifndef SOFTSERIAL_IGNORE_PCINT2
#if defined(PCINT2_vect)
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
#endif
#endif

##ifndef SOFTSERIAL_IGNORE_PCINT3
#if defined(PCINT3_vect)
ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
#endif
#endif 

This modification would leave all existing projects working, but gives future users the ability to ignore ISR creation if they don't need it explicitly.

Kind regards,
Martin

@matthijskooijman
Copy link
Collaborator

Why is SoftwareSerial defining ISR for all possible PinChangeInterrupt vectors? Even if not all of them are used, the ISR is registered and prevents others (e.g. other libs) from registering PinChangeInterrupts.

This is indeed an issue, but tricky to fix, because the pin numbers you run SoftwareSerial on are passed to SoftwareSerial on runtime, while it must be decided at compile/link time whether or not the ISR is included or not. Of course, when you only pass constants to the SoftwareSerial, in theory, the compiler could figure out at compiletime which pins you (might) use and include only the ISRs for that. However, there's no easy way to actually do this in C++, unfortunately (you can use template arguments, but that forces the pin numbers to be compile-time constants, duplicates code, and also is trickier to use).

One way that you can use, is explicitly choosing ISRs using the preprocessor, which is essentially what you also propose. This could work, but is also tricky to use in the current Arduino ecosystem, since there is no real supported way for a sketch to influence the preprocessor (not sure if this is intentional or just lacking a properly usable implementation. There are some open issues about this, I think).

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

2 participants