I am trying to write a function which can check the type of digital pin (INTx, PCINTxx or ICP). How to check if the pin type is of ICP (input capture pin) ?
My function looks something like following. I have figured how to check if pin is of INTx or PCINTxx type, but don't know how to check if pin is ICP type.
AltSoftSerial(uint8_t rx_pin, uint8_t tx_pin) {
if( ? ? ? ? ) { // if ICP pin
// do something
}
else if(digitalPinToInterrupt() != NOT_A_INTERRUPT) { // check if INTx pin
// do something
}
else if (digitalPinToPCMSK(rx_pin) != 0) { // check if PCINTxx pin
// do something
}
...
}
I am modifying the AltSoftSerial library. In the library only ICP pin can be used as Rx pin. I am changing the library so INTx or PCINTx pins can also be used as rx pin.
The "DigitalPinToXXX" macros/functions that currently exist are provided explicitly by the Arduino core code referencing a table, rather than than any inherent hardware ability. There's no equivalent for the ICP pins, so you'll have to create one. Um: ATmega328 only has 1 ICP pin, and ATmega2560 only has 2 that are connected (out of four total.)
So presumably you want something like:
static uint8_t* digitalPinToInCompareRegister(uint8_t p) {
#if defined(__AVR_ATmega328__)
if (p == 8) return &ICR1; // timer1 has ICP
#elif defined(__AVR_ATmega2560__))
if (p == 49) return &ICR4; // timer4 has ICP
if (p == 48) return &ICR5; // timer5 has ICP
/* ICR3==PE7, ICR1==PD4, but these are not connected to pins on Arduino MEGA */
#endif
return 0;
}
There's an existing digitalPinToTimer() macro, but it doesn't give you any indication of whether it's a 16bit timer with ICP, or an 8bit timer without ICP...
If you're trying to use ALL the ways that a transition on a pin might generate an interrupt, you can also think about using the timer external clock pins (T0 and T1 on m328; I can't find T2) with the value pre-set to "one less than overflow" or "one less than output compare match." It requires completely repurposing the timers, though.