Modification on the Port and Digital Pin of SAMD21g18a

Hi,

I am using the SAMD21G18A in a custom board and I am using the MKRZERO bootloader.

I got stuck on modifying the GPIO pins now. For example, PA22 is predefined as D0, so I can assign a LED pin to pin 0, like LED = 0. However, if I want to use other GPIOs which are not shown in the MKRZERO board's IO, what should I do in the firmware? For instance, I would like to use PA18, how can I define it.

Based on some researches I did, I know we can modify some pins on variant.h and variant.c. I saw the places that I can change SPI, I2C, UART channels and analog pins, but I don't see a place I can add the GPIOs.

Anyone could help me out?

Welcome to the forum.

Did you try to modify the PinDescription g_APinDescription in variant.cpp?

I would recommend you look at the differences between two Arduinos that use the same chip but have different pin outs. e.g., Nano 33 IoT, MKR WiFi 1010 both use the SAMD21 but they are slightly different. e.g., the MKR has a additional analog to measure the external battery circuit.

Hi @charles951575

To set a port pin (PA14) as an output:

PORT->Group[PORTA].DIRSET.reg = PORT_PA14;

To set the port pin as an input:

PORT->Group[PORTA].DIRCLR.reg = PORT_PA14;
PORT->Group[PORTA].PINCFG[14].bit.INEN = 1;

To set the port pin output high:

PORT->Group[PORTA].OUTSET.reg = PORT_PA14;

To set the port pin output low:

PORT->Group[PORTA].OUTCLR.reg = PORT_PA14;

To toggle the port pin high and low:

PORT->Group[PORTA].OUTTGL.reg = PORT_PA14;

To activate the pin's pull-up resistor:

PORT->Group[PORTA].PINCFG[14].reg |= PORT_PINCFG_PULLEN;

or alternatively:

PORT->Group[PORTA].PINCFG[14].bit.PULLEN = 1;

To activate the pin's input pull-down resistor:

PORT->Group[PORTA].OUT.reg |= PORT_PA14;
PORT->Group[PORTA].PINCFG[14].reg |= PORT_PINCFG_PULLEN;

or alternatively:

PORT->Group[PORTA].OUT.reg |= PORT_PA14;
PORT->Group[PORTA].PINCFG[14].bit.PULLEN = 1;

To increase the pin's driver strength (from 2mA to 7mA):

PORT->Group[PORTA].PINCFG[14].reg |= PORT_PINCFG_DRVSTR;

or alternatively:

PORT->Group[PORTA].PINCFG[14].bit.DRVSTR = 1;

Note that OUTSET and OUTCLR perform a bitwise set and clear operation respectively on the OUT register, with the read-modify-write performed in hardware. Writing to the OUT register directly requires the use of bitwise OR (|=) and AND (&= ~) operators.

Thanks, Klaus. It works. The digital pin number actually depends the line number on the variant.cpp.

1 Like