SERCOM機能でGPIOが足りない話②

<<[前回](https://qiita.com/conel_fg/items/9066b866f7a0d18001a8) :Arduino IDEでSERCOMを使ったプログラムを書く
=今ｺｺ= :マイコンのGPIOの名前・SERCOMとGPIOの選び方
\>>[次回](https://qiita.com/conel_fg/items/c45c156939a41ff6f03c) :ATSAMD2xとATSAMD5xの違いについて

## この記事の対象
* プロトタイピングに慣れてきたひと
* いっぱいセンサを使うデバイスを作りたいひと
* Arduinoを活用したハードウェア開発に興味があるひと

## 概要
* AVR系のマイコンで余りまくっていたデジタル・アナログのGPIOについて，SAM系マイコンならシリアル通信に再定義して有効活用できるぞっていう話
* ArduinoやAdafruitの公式リファレンス以外の情報が少なかったので記事にしました．
* **今回はSERCOM機能のハードウェア的な面について取り扱います．**

## マイコンのGPIOとSERCOM

### GPIOの名前と機能
[前回](https://qiita.com/conel_fg/items/9066b866f7a0d18001a8)でSERCOM機能を使うことで任意にシリアルポートを増やせると書きましたが，SERCOMはどのGPIO，どの組み合わせでも任意に再定義して使用できるわけではありません．
どのGPIOが使えるかは次の2点を見ればわかります．

1. マイコンのデータシートにある「Multiplexed Signals」の表
* 各Arduinoボードの回路図．

Arduino系に用いられているSAM系マイコンのデータシートは以下の２種類です．

* [ATSAM D2xシリーズ(Adafruit Metro M0やArduino M0などに搭載)](https://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf)
* [ATSAM D5x/E5xシリーズ(Adafruit Metro M4などに搭載)](https://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5x_E5x_Family_Data_Sheet_DS60001507G.pdf)

![ATSAMD21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373248/91f9e66c-71fc-5111-6abf-bc4a8de27507.png)

上図は[ATSAM D2xシリーズのデータシート](https://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf)の22ページからの抜粋です．
この図から，マイコンには見かけ上のピン番号の他に「PA〜」や「PB〜」など，GPIOに名前がつけられていることがわかります．

### SERCOMとSERCOM_ALT

データシート30ページ以降の表には，この「PA〜」ごとの機能について，詳細に記載されています．
以下に表の一部を抜粋します．

| Pin | SERCOM | SERCOM_ALT |
|:-:|:-:|:-:|
|  PA08 | SERCOM0/PAD[0] | SERCOM2/PAD[0] |
|  PA09 | SERCOM0/PAD[1] | SERCOM2/PAD[1] |

上の表によれば，PA08というGPIOはSERCOM0/PAD[0]と，SERCOM2/PAD[0]という機能を持っています．
SERCOM0/PAD[0]を使用する場合と，SERCOM2/PAD[0]を使用する場合とでは，ArduinoIDEのプログラム上で「SERCOM」と「SERCOM_ALT」と定義することで区別できます．

ここで，Adafruit Metro M0 ExpressではPA08はD4，PA09はD3に当たるので，動作や使用するGPIOが前回のプログラムと同じになるような以下のプログラムを書くことができます．

```C++
#include <Arduino.h>        //必須
#include "wiring_private.h" //必須

#define TX 4
#define RX 3

//Uart mySerial(&sercom2, RX, TX, SERCOM_RX_PAD_1, UART_TX_PAD_0); // 前回=SERCOM_ALTを使用する場合
Uart mySerial(&sercom0, RX, TX, SERCOM_RX_PAD_1, UART_TX_PAD_0);   // 今回=SERCOMを使用する場合 

void setup() {
  mySerial.begin(115200);
  
  //pinPeripheral(TX, PIO_SERCOM_ALT); // 前回=SERCOM_ALTを使用する場合
  //pinPeripheral(RX, PIO_SERCOM_ALT); // 前回=SERCOM_ALTを使用する場合
  pinPeripheral(TX, PIO_SERCOM);       // 今回=SERCOMを使用する場合 
  pinPeripheral(RX, PIO_SERCOM);       // 今回=SERCOMを使用する場合 
  
}

void loop() {
  /****処理内容****/
}
/*
void SERCOM2_Handler() // 前回=SERCOM_ALTを使用する場合
{
  mySerial.IrqHandler();
}
*/
void SERCOM0_Handler() // 今回=SERCOMを使用する場合
{
  mySerial.IrqHandler();
}
```
### GPIOの選び方

ATSAM D2xシリーズではSERCOM0~5まで存在します．
また，PADは[0]~[3]まで存在します．

SERCOMに使用するGPIOの組み合わせには，SERCOMとPADの数値に対し，以下のような条件が存在します．

1. シリアルポートの組み合わせは**必ず同じ番号のSERCOM内から選ぶ必要があります**．
* UARTにおいて，**TXの役割をもつことができるのはPAD[0]またはPAD[2]**のGPIOです．
* I2Cにおいて，**SDAはPAD[0]，SCLはPAD[1]**でなければなりません．
* SPIにおいて，**SCKはPAD[1]またはPAD[3]であり，MOSIはPAD[1]以外**でなければなりません．

条件2については，SERCOMとSERCOM_ALTを区別することで，番号被りを回避することができます．

なお，ATSAM D5x/E5xシリーズにおけるGPIOの選び方は上記とは異なる部分があります．
これについては次回取り扱います．

## BootloaderとGPIO

ここまでの説明やプログラムは基本的に「Adafruit Metro M0 Express」の使用を前提としています．
つまり，他のマイコンボードでは同様の動作が望めないということです．

これは，D4 = PA08という定義が他のマイコンボードでは成り立たないからです．

Arduino IDE上でのピン番号とマイコンの「PA〜」などの対応はBootloaderで定義されています．
Arduino公式ストアやAdafruit社は，同社が販売している以下のような，各種マイコンボードの回路図や基板データを公開しています．

1. [Arduino MKR WAN 1310](https://store.arduino.cc/usa/mkr-wan-1310)
* [Arduino Zero](https://store.arduino.cc/usa/arduino-zero) 
* [Adafruit Metro M0 Express](https://learn.adafruit.com/adafruit-metro-m0-express-designed-for-circuitpython/downloads)
* [Adafruit Feather M0 Express](https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython/downloads)
* [Adafruit Metro M4 Express](https://learn.adafruit.com/adafruit-metro-m4-express-featuring-atsamd51/downloads)
* [Adafruit Feather M4 Express](https://learn.adafruit.com/adafruit-feather-m4-express-atsamd51/downloads)

以下は「Adafruit Metro M0 Express」の回路図の一部です．
これを見ると，A0 = PA02 など，各GPIOとマイコンの「PA〜」の紐付けがわかります．
これと上記GPIOの選び方の条件を照らし合わせていくことで，適切なGPIOを選択することができます．

![Adafruit_Metro_M0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373248/4715a7e6-3f79-9e15-9843-e249483f1d07.png)

##今回のまとめ
今回はGPIOにはマイコンの見かけ上の番号・役割別の名前・Arduino IDE上での名前があるということやSERCOMを使用できるGPIOの選び方を紹介しました．

個人的には「PA〜」とArduino IDE上での名前はどのボードでも一致させてほしいなぁと思いました．
いちいち参照するのは面倒ですし，対応表などを作成することをおすすめします．