When the sketch shown at end-of-question is compiled and uploaded to an Arduino board, it is supposed to Serial-print a list of available digital pins, showing for each pin whether it supports PWM or PCINT. (For the latter items, it should indicate whether it has timer-supported PWM, and whether it can cause a hardware-supported pin-change-interrupt.) For example, for an ATmega-2560 board, the program's output includes lines like
Pin# Port Mask PWM PCINT
11 PB5 0x20 PWM PCINT5 PCINT0_vect
46 PL3 0x08 PWM
52 PB1 0x02 PCINT1 PCINT0_vect
Using arduino 1.6.3 on my Ubuntu 14.04 system with an ATmega-2560 board, the program's output for pins 14 and 15 is:
14 PJ1 0x02
15 PJ0 0x01
As I understand it, those pins should be shown⁽¹⁾ as supporting PCINT9 and PCINT10, with vector PCINT1_vect, but the program doesn't report them as such. What is this problem due to?
⁽¹⁾See, for example, table 13.3.9, Alternate Functions of Port J, in doc2549.pdf, the spec sheet for ATmega640/1280/1281/2560/2561. Also see Why is my interrupt code not working?.
Sketch pinsList.ino:
/* pinsList -- JW, 4 October 2015 --
*
* Displays a list of Arduino pin numbers for current kind of Arduino
* board, along with port codes, pin-change-interrupt numbers, and
* pin-change-interrupt vector numbers.
*
* Here are two examples of output lines for pin 11, the first for an
* Uno, the second for a Mega:
*
* 11 PB3 0x04 PWM PCINT3 PCINT0_vect
* 11 PB5 0x20 PWM PCINT5 PCINT0_vect
*/
//-----------------------------------------------------------
// Given a value with 1 bit set, return bit #. Else return 9.
byte getBitfromBV (byte m) {
byte b=0, v=1;
while (v) {
if (m==v)
return b;
++b; v <<= 1;
}
return 9;
}
//-----------------------------------------------------------
void processPinNumber(byte pin) {
char buffi[128]; // We create text-to-write in buffi
byte nbuff=0; // #chars used in buffi
byte nPCICR; // 0, 1, or 2 for mask-register #
byte bitInByte; // 0 to 7 for bit in I/O mask
byte pinPort; // pin's port #, in range 1 to 12
byte PCInum; // PCINT# if pin is a PCI pin
char *portLet = "?ABCDEFGHIJKL";
if (pin >= NUM_DIGITAL_PINS) return;
pinPort = digitalPinToPort(pin); // Get port #, in range 1 to 12
bitInByte = getBitfromBV(digitalPinToBitMask(pin));
nbuff = snprintf(buffi, sizeof(buffi), " %2d P%c%d 0x%02x",
pin, portLet[pinPort], bitInByte, 1<<bitInByte);
// Indicate if it's a PWM pin
if (digitalPinHasPWM(pin)) {
nbuff += snprintf(buffi+nbuff, sizeof(buffi)-nbuff, " PWM");
} else {
nbuff += snprintf(buffi+nbuff, sizeof(buffi)-nbuff, " ");
}
// If it's a PCINT pin, show its PCINT number and 0, 1, 2 for its vector #
if (digitalPinToPCICR(pin)) { // Is it a PCint pin?
nPCICR = digitalPinToPCICRbit(pin); // 0, 1, 2 for pin's PCICR bit#
PCInum = nPCICR*8 + bitInByte;
nbuff += snprintf(buffi+nbuff, sizeof(buffi)-nbuff,
" PCINT%d PCINT%d_vect", PCInum, nPCICR);
}
Serial.println(buffi);
}
void setup() {
delay(50);
Serial.begin(115200);
delay(50);
while (!Serial) ; // wait for serial stream to connect
Serial.println("\nPin# Port Mask PWM PCINT");
for (byte p=0; p<NUM_DIGITAL_PINS; ++p)
processPinNumber(p);
Serial.end();
}
void loop() {
}