Want to use PA13/PA14 on MKR Zero - SERCOM modification needed?

Hi,
I have a custom board based on SAMD21... and use the Arduino MKR Zero board for programming it. Now I have to use PA13/PA14 as digital port pins.
I understood that this pins are used for the SPI interface SERCOM2 in the Arduino MKR Zero configuration. How can I change this mapping definition? I assume that PA13/PA14 can be used after modifying this cryptic mapping table. I would be glad for having a hint to a solution.
best regards
Tobias

Hi @tobiasgomer

It's possible to change the pin mapping in the Arduino SAMD21 core code files: variant.h and variant.cpp. However, these will be overwritten whenever Arduino perform an update to the SAMD21 boards package.

It's probably easiest to just clear the peripheral multiplexer enable (PMUXEN) bit in PA13's and PA14's respective pin configuration (PINCFG) registers. The following lines of code will cause these pins to become GPIO:

PORT->Group[PORTA].PINCFG[13].bit.PMUXEN = 0;
PORT->Group[PORTA].PINCFG[14].bit.PMUXEN = 0;

Thereafter it will be possible to control them using the standard Arduino pinMode(), digitalRead() and digitalWrite() functions.

On the Arduino MKR Zero, port pins PA13 and PA14 map to Arduino digital pins 27 and 28 respectively.

They're supposed to connected to the SD card socket. AFAIK, they won't even be initialized via the SERCOM unless you include libraries that initialize SPI or the SD card. For example, the Blink example sketch compiles to code that never references SPI or Sercom4.

So you should just be able to using pinMode and digitalWrite/etc on pins 27 and 28 with no special effort.

1 Like

Thanks a lot - you made my day. It is obviousely not necessary to change that
mapping, using 27 and 28 works like a charme for digitalRead(). But attaching interrupts does not work.

const int buttonPin = 28; 
attachInterrupt(digitalPinToInterrupt(buttonPin), PA14_ISR, FALLING);

This seems to be according to

MKR Family boards 0, 1, 4, 5, 6, 7, 8, 9, A1, A2

as described in the docu to attachInterrupt(). Although digitalPinToInterrupt(buttonPin) returns 28.

Do you have a pointer to the document where I can find those PIN mappings?

Ok, I understood. And I understood that the variant.cpp reflects the board MKR Zero's design. Now I could create a custom board with a modified variant.cpp. The disadvantage would be to lose the support on ongoing SAMD developments, right?
Isn't there a way to modify this g_APinDescription[] at run time? Doing so using the debugger fails...

I think you can create a new board that uses an existing "core", and so includes little more than "boards.txt" and the new variants directory. I'm not sure that there are any popular examples of this, but it used to be used when adding something like the nearly identical ATmega88p to the standard AVR core.

Adding variants and changing boards.txt of an existing core doesn't cause you to lose changes, exactly, it's just that updates will over-write your changes and you'll have to apply them again.

Interrupts on SAMD are a bit odd. In theory, any pin can be used for interrupts, but there are only 16 possible interrupts, and two pins cannot use the same interrupt at the same time (WHICH interrupt a pin generates is hardwired.) I think the core handles this by picking pins that work with each interrupt.

Isn't there a way to modify this g_APinDescription[] at run time?

It's normally built in flash ("const"); I suppose if it was moved to RAM you could modify it at runtime. It sounds like a really bad idea, though. What were you hoping to accomplish? Most pins can be fully controlled outside of the normal Arduino functions - for example, I've been able to set up all 6 SERCOMs as UARTs on a sparkfun D21 board (that exposes all the pins) - no modifications to g_APinDescription needed.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.