Is it possible to use all the I/O pins of the SAMD21G18A using the arduino IDE?

Hello i am planning on making my own custom board, and i have chosen the micro controller of the new arduino boards, the SAMD21G18A. I like it because it has its own internal clock and can be wired directly to a usb port without any other converters.

Another reason for liking it is because from the datasheet it says:

• I/O – Up to 52 programmable I/O pins

Which i will be needing (36 pins to be exact), i did consider using the due's uController but the circuit looks really complicated. Now on the arduino nano IOT only uses a combined total of 21 I/O pins (analog and digital) out of 38 on the pinout of SAM21G18A

I do want to program still the SAM21G18A using the arduino IDE since it is what i have experienced with, and has all the libraries that i will need. Will i still be able to use the 17 unmapped pins ? if so, how will i address them, on that note how will i know which pin is D1 or A1.

also it says that i can run this uController at 98mhz, if i am able to run it at that speed, do i need to change somehthing in IDE for the delays to be accurate?

You would have to create a new board type with its own "variant.cpp" that maps all of the pins you want to use. This will be comparatively easy, if you don't care about alternate functionality (ADC, Sercom, timers/pwm, interrupt, etc)
variant.cpp (and variant.h) are relatively obvious. For SAMD, there's a big array:

const PinDescription g_APinDescription[]=
{
  // 0..13 - Digital pins
  // ----------------------
  // 0/1 - SERCOM/UART (Serial1)
  { PORTA, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // RX: SERCOM0/PAD[3]
  { PORTA, 10, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // TX: SERCOM0/PAD[2]

  // 2..12
  // Digital Low
  { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 },
  { PORTA,  9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1]
  { PORTA,  8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI },  // TCC0/WO[0]
     :
     :
  // 38..41 - EDBG/Digital
  { PORTA, 13, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH5, NOT_ON_TIMER, EXTERNAL_INT_13 }, // EIC/EXTINT[13] *TCC2/WO[1] TCC0/WO[7]
  { PORTA, 21, PIO_PWM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH7, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 7
  { PORTA,  6, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH0, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 8
  { PORTA,  7, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH1, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 9

  // 42 (AREF)
  { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP

  // ----------------------
  // 43 - Alternate use of A0 (DAC output)
  { PORTA,  2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT
} ;

that maps "Arduino pin number" to everything else. Adding strictly digital pins would mean adding a bunch of lines similar to the line for pin2, probably at the end (so as not to conflict with existing boards.)

also it says that i can run this uController at 98mhz

Really? I think it says that the PLL clock can output up to 96MHz, but you have to divide it down to less than 48MHz before you can actually use it for much of anything...

Thank you for replying.

I will be needing pwm and interrupts, 8 pwm pin and 2 interrupt pins. In a sense it is just like the arduino Nano IOT but with extra digital input pins

another way to look at it:

can i do port manipulation through the registers? on those extra pins i will only be doing digital reads so i only need this 2 functions

pinMode() - enabling internal pull-up
digitalRead() - reading pin state

On your code sir i am a bit confused, is this what the current variant.h/cpp of the samd21 or have you already modified this sir?

@Juraj Thi is quite well beyond me as of the moment sir and has not gone to that point yet, Thank you for sharing this i will use it as a reference when i get to that point :slight_smile:

I will be needing pwm and interrupts, 8 pwm pin and 2 interrupt pins. In a sense it is just like the arduino Nano IOT but with extra digital input pins

If you only ADD pins, they can be "beyond" the existing pins, and you can put your PWM and Interrupts on the original pins...

can i do port manipulation through the registers?

Yes, that's another way to do it. You can always access the ports through registers, whether or not you define them as "Arduino Pins."

knox41234:
@Juraj Thi is quite well beyond me as of the moment sir and has not gone to that point yet, Thank you for sharing this i will use it as a reference when i get to that point :slight_smile:

it is very simple. you copy and edit a few files

westfw:
Yes, that's another way to do it. You can always access the ports through registers, whether or not you define them as "Arduino Pins."

Thats great news, i think i will go with that since there will less chance of me messing up something that i shouldnt.

Do you know what are the registers names for setting up the internall pullup and reading the pins state?

is it the same as the old arduino nano

DDRA , DDRB , PORTA , PORTB

and since the microcontroller is 32bits i would assume you do it like this?

DDRA = 00000000 00000000 0000000 00000000
alternatively
DDRA = 0xFFFF

please correct me if im wrong

No. Nano is 8-bit AVR, a completely different architecture. Direct port manipulation on SAMD21 is a little more involved. Most of the macros are defined in variant.h. The way I learned to do it was by studying the technique used by the PJRC Rotary Encoder Library. That only does reads, but writes would be done in a similar fashion based on the info in variant.h.

EDIT:
Also, look at how pinMode(), digitalWrite() and digitalRead are implemented for the SAMD21 in wiring_digital.c.

upon lookin at the variant.h on the arduino nano iot 33 it would seem all pin ARE ALREADY mapped in the API


image link: image hosted at ImgBB — ImgBB
insert image seems not to be working

So this means i am good to go right ???