SAM 15x15 package information
Just for nerds
This article is a comprehensive description of Arduino SAMD21 installation packages. Note that for the use of the SAM 15x15 board, you don't have to read this. Just read the quick start guide.
Github
I made a package for the SAM15x15 on GitHub and https://github.com/boseji optimized the package in 2020.
See the for new releases: press "tags" in the master / branch / tags menu on GitHub.
Pinout
SAMD21G development board 15x15mm (Arduino compatible)
To use non standard Arduino boards, such as the Arduino Zero, we have to install an appropriate package, which describes the processor and pins.
Arduino Zero package
The SAM15x15 package is derived from the Arduino Zero package, see GitHub here.
The Arduino Zero board is pin-compatible with older boards, such as the Arduino Uno. The drawback of this compatibility is that just a part of the SAMD21 pins is connected to the three pin headers; the rest of the pins is not used. Not all pin functions are declared in the Arduino Zero variant.cpp file. For instance, besides A0...A5, pin 3 has an analog input too, but it can't be used.
SAM 15x15 package
In order to make all SAMD21G pins available, install the SAM 15x15 package. This package is derived from the Arduino Zero (package: Arduino SAMD Boards (32-bit ARM Cortex-M0+) where these 6 files are modified:
- variant.cpp
- variant.h
- WVariant.h
- wiring_analog.c
- samd21_host.c
- boards.txt
In contrast to the Arduino Zero, all functions of a pin, such as INT, ADC and PWM are declared also and can be used.
TODO: It would be nice to extend the original Arduino Zero package for using all pins, then separate packages are no longer needed for the SAM15x15 and other boards.
1 variant.cpp
This files describe the pin functions and is located here:
C:\Users\your-name\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.6\variants\arduino_zero\variant.cpp
// 29-8-2015 15x15 van Dalen, added extra pins D25..D33, not Arduino compatible // 29-8-2015 15x15 van Dalen, added INT, ADC, PWM and timer where possible #include "variant.h" const PinDescription g_APinDescription[]= { // ----------------------------------- Arduino compatible pins ----------------------------------- // Digital low D0..D7 { PORTA, 11, PIO_SERCOM, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel19, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_11 }, // p16 Serial1 RX { PORTA, 10, PIO_SERCOM, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel18, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_10 }, // p15 Serial1 TX { PORTA, 14, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_14 }, // p13 { PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // p14 { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // p23 { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // p14 { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, // p29 { PORTA, 21, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_5 }, // p30 // Digital high D8..D13 { PORTA, 6, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // p11 { PORTA, 7, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // p12 { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // p27 { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // p25 MOSI { PORTA, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // p28 MISO { PORTA, 17, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // p26 SCK // D14..D19, analog A0..A5 { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // p3 10bit DAC { PORTB, 8, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel2, PWM4_CH0, TC4_CH0, EXTERNAL_INT_8 }, // p7 { PORTB, 9, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel3, PWM4_CH1, TC4_CH1, EXTERNAL_INT_9 }, // p8 { PORTA, 4, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // p9 { PORTA, 5, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // p10 { PORTB, 2, PIO_ANALOG, 0, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // p47 // SDA/SCL, I2C D20..D21 { PORTA, 22, PIO_SERCOM, (PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM4_CH0, TC4_CH0, EXTERNAL_INT_6 }, // p31 SDA { PORTA, 23, PIO_SERCOM, (PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM4_CH1, TC4_CH1, EXTERNAL_INT_7 }, // p32 SCL // SPI D22..D24 { PORTA, 12, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_12 }, // p21 { PORTB, 10, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH0, TC5_CH0, EXTERNAL_INT_10 }, // p19 { PORTB, 11, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH1, TC5_CH1, EXTERNAL_INT_11 }, // p20 // ----------------------------------- Extra pins, Arduino compatible numbering D25..D26 ----------------------------------- { PORTB, 3, PIO_TIMER, PIN_ATTR_DIGITAL, ADC_Channel11, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // p48 previously RX LED { PORTA, 27, PIO_TIMER, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // p39 previously TX LED // ----------------------------------- Extra pins, no Arduino compatible numbering D27..D33 -------------------------------- { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // p4 AREF, problem with analogRead and digitalRead { PORTA, 13, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_13 }, // p22 { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // p37 { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // p38 { PORTA, 28, PIO_TIMER, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // p41 { PORTA, 30, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_10 }, // p45 { PORTA, 31, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_11 }, // p46 } ;
Protection of native USB port
In order to make the native USB port invulnerable to the native USB port virus, the USB pins 45 and 46 on the SAMD21 are not included in the variant.cpp file.
2 variant.h
This file contains definitions and is located here:
C:\Users\your-name\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.6\variants\arduino_zero\variant.cpp
Pin sequence
Because of compatibility with the Arduino Zero, the pin numbering is mixed up, as you can see in the 2 columns "No": 14
27, 15... For clarity, the Arduino pin numbers are used as e.g. digitalRead(14). Note that the Arduino pin numbers are the pin order in the PinDescription array in variant.cpp.
To create a pin sequence from 0,1, 2 ... 33, a pin number conversion array is created with d[], see the 2 columns "I/O".
Example:
digitalRead(d[0]) is equal to digitalRead(14).
//SAM 15x15 pin sequence static const int d[]={ 14, 27, 15, 16, 17, 18, 8, 9, 4, 3, 1, 0, 23, 24, 22, 28, 2, 5, 11, 13, 10, 12, 6, 7, 20, 21, 29, 30, 26, 31, 32, 33, 19, 25 }; static const int pinCount = 34;
// LEDs #define PIN_LED_RXL (25u) // 15x15 can be comment out if unused #define PIN_LED_TXL (25u) // (26u) 15x15 combine RXL and TXL to one LED
/* * USB */ //#define PIN_USB_HOST_ENABLE (27ul) 15x15 the SAM 15x15 doesn't use PIN_USB_HOST_ENABLE
3 WVariant.h
This file contains definitions and is located here:
C:\Users\ your-name \AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.6\cores\arduino
/* Definitions and types for pins */ typedef enum _EAnalogChannel { No_ADC_Channel=-1, ADC_Channel0=0, ADC_Channel1=1, ADC_Channel2=2, ADC_Channel3=3, ADC_Channel4=4, ADC_Channel5=5, ADC_Channel6=6, ADC_Channel7=7, ADC_Channel10=10, // 15x15 changed from here ADC_Channel11=11, ADC_Channel16=16, ADC_Channel17=17, ADC_Channel18=18, ADC_Channel19=19, DAC_Channel0, } EAnalogChannel ;
4 wiring_analog.c
This file contains analog functions and is located here:
C:\Users\ your-name \AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.6\cores\arduino
/* SAM15x15 if (pin < A0) { pin += A0; }*/
5 samd21_host.c
This file contains USB functions and is located here:
C:\Users\ your-name \AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.6\cores\arduino\USB
#ifdef PIN_USB_HOST_ENABLE // 15x15 the SAM 15x15 doesn't use this pin // Put VBUS on USB port pinMode( PIN_USB_HOST_ENABLE, OUTPUT ); digitalWrite( PIN_USB_HOST_ENABLE, HIGH ); #endif
6 boards.txt
Change arduino_zero_native to SAM15x15:
# SAM 15x15 (only native USB port) # --------------------------------------- SAM15x15.name=SAM 15x15 SAM15x15.vid.0=0x2341 SAM15x15.pid.0=0x804d SAM15x15.vid.1=0x2341 SAM15x15.pid.1=0x004d SAM15x15.vid.2=0x2341 SAM15x15.pid.2=0x824d # If the board is a 2341:824d use 2341:824d for build and set other parameters as well SAM15x15.vid.2.build.vid=0x2341 SAM15x15.vid.2.build.pid=0x824d SAM15x15.vid.2.build.usb_product="Genuino Zero" SAM15x15.vid.2.bootloader.file=zero/samd21_sam_ba_genuino.bin SAM15x15.vid.3=0x2341 SAM15x15.pid.3=0x024d # If the board is a 2341:024d use 2341:824d for build and set other parameters as well SAM15x15.vid.3.build.vid=0x2341 SAM15x15.vid.3.build.pid=0x824d SAM15x15.vid.3.build.usb_product="Genuino Zero" SAM15x15.vid.3.bootloader.file=zero/samd21_sam_ba_genuino.bin SAM15x15.upload.tool=bossac SAM15x15.upload.protocol=sam-ba SAM15x15.upload.maximum_size=262144 SAM15x15.upload.use_1200bps_touch=true SAM15x15.upload.wait_for_upload_port=true SAM15x15.upload.native_usb=true SAM15x15.build.mcu=cortex-m0plus SAM15x15.build.f_cpu=48000000L SAM15x15.build.usb_product="Arduino Zero" SAM15x15.build.usb_manufacturer="Arduino LLC" SAM15x15.build.board=SAMD_ZERO SAM15x15.build.core=arduino SAM15x15.build.extra_flags=-D__SAMD21G18A__ {build.usb_flags} SAM15x15.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld SAM15x15.build.openocdscript=openocd_scripts/arduino_zero.cfg SAM15x15.build.variant=arduino_zero SAM15x15.build.variant_system_lib= SAM15x15.build.vid=0x2341 SAM15x15.build.pid=0x804d SAM15x15.bootloader.tool=openocd SAM15x15.bootloader.file=zero/samd21_sam_ba.bin
Using the SWD pins SWDIO and SWCLK for general in / out
The SWD pins SWDIO and SWCLK are used for programming at the Arduino Zero or SAM 15x15. Also the program port communication to the SAMD21 of the Arduino Zero goes trough these pins. Atmel is not very clear about what happens when these 2 pins are also used for I/O, therefore clarification will be given here.
The SWD port explained
See the Atmel story of the Serial Wire Debug (SWD) port HERE.
SWDIO
The SWDIO pin can be used safely for I/O without disturbing the SWD:
// the SWDIO pin can be used safely for I/O const int SWDIO = 33; pinMode(SWDIO, OUTPUT); digitalWrite(SWDIO, 0);
SWCLK
If the SWCLK pin is used for I/O, the SWD functionality will be disabled. You can recover this by reset the board by the button.
Using the SWCLK as digital output has a peculiarity too, it requires a patch.
// don't use the SWCLK pin for I/O, this disables the program port const int SWCLK = 32; pinMode(SWCLK, INPUT); // patch to use the SWCLK pin as output pinMode(SWCLK, OUTPUT); digitalWrite(SWCLK, 0); // The program port is disabled now...
How to connect LED's and other loads to a microcontroller
For the SAMD21, the outputs can supply just 7mA, in contrast to 14mA at the ATmega328.
The GND pins together can carry more current than the 3.3V VDD pin: 130mA respectively 92mA. Therefore, it is not arbitrary whether loads are connected to the power supply (see A) or the ground (see B). In order to let flow the load current through the processor ground pins, it is advisable to connect loads between the processor outputs and the supply voltage (see A):
How to connect LED's and other loads to a microcontroller
Notes
- AREF has become another number (d4) and is not number compatible with the Arduino Zero anymore.
- The bootloader has nothing to do with the package file for the pin definitions.
To do
- Using SWCLK pin as output has a bug
https://forum.arduino.cc/index.php?topic=431503.0 - analogWrite() has to be disabled before the pin can get another I/O function.
https://forum.arduino.cc/index.php?topic=431501.0 - analogRead and digitalRead doesn't work on AREF
https://forum.arduino.cc/index.php?topic=434775.0
Improvements
If you have improvements then please let me know.
NEW: Mini SAMD21 development board 15x15mm (Arduino compatible)
The smallest Arduino compatible SAMD21 board: 15x15 mm, 34 I/O pins
The SAM 15x15 is an Arduino development board of just 15 x 15mm, with the same powerful controller as the Arduino Zero: the SAMD21G18. Despite the small size, it has more I/O pins than the Arduino Zero: 34 instead of 20. See the article and how to buy here.