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

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

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

## 概要
* AVR系のマイコンボード(Arduino UNOなど)で余りまくっていたGPIOについて，SAM系マイコンならシリアル通信に再定義して有効活用できるぞっていう話
* ArduinoやAdafruitの公式リファレンス以外の情報が少なかったので記事にしました．
* **今回はSERCOMについて，前回・前々回の細かい補足をします．**

## SAMマイコンの種類と違い

前回Arduinoで使用されているSAMマイコンは以下の2種類だと記載しました．
SAMマイコンはこの「2」や「5」の数値が大きいほど上位機種です．
ただし，Arduinoはあくまで教育用のマイコンボードの側面があるため，開発上の違いをあまり感じないよう工夫されているように感じます．

* [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)

ここではSERCOMを使う際，ATSAM D2xシリーズとATSAM D/E5xシリーズで異なる部分に焦点を当てていきます．

### GPIOの選び方
SERCOMに使用するGPIOの組み合わせには以下のような条件があると前々回記載しました．

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]以外**でなければなりません．

しかし，上記はATSAM D2xシリーズにのみ適用可能です．D/E5xシリーズでは条件が若干厳しくなります．
それが以下です．

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

しかしながら，D/E5xシリーズでは，上記の条件は，SERCOMとSERCOM_ALTの使い分けにより，厳しくなったとは感じにくくなっています．

### SERCOMとSERCOM_ALT

ATSAM D2xシリーズ同様，[ATSAM D5x/E5xシリーズのデータシート](https://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5x_E5x_Family_Data_Sheet_DS60001507G.pdf)32ページ以降の表には，GPIOの機能について，詳細に記載されています．
以下に表の一部を抜粋します．

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

ここで，ATSAM D2xシリーズと異なり，SERCOMとSERCOM_ALTでPADのナンバーが変わっていることがわかります．
GPIOの条件ではTXはPAD[0]のみに減ってしまったものの，SERCOMとSERCOM_ALTで２種類の機能をもつことで，単純な機能の縮小を防いでいる感じです．

### シリアルハンドラ関数

上記を踏まえ，ソースコードに影響のある部分としてシリアルハンドラ関数について説明します．
ATSAM D2xシリーズでは，使用するGPIOが決定すれば，SERCOMおよびそのPADのナンバーは完全に決定できましたが，ATSAM D5x/E5xシリーズでは上記の通り，SERCOM・SERCOM_ALTの選択でPADのナンバーが変わるため，ハンドラ関数も別々に宣言する必要があります．

```C++
//mySerial：Uartクラスの名前
//関数名のSERCOMxのxは使用するSERCOMのナンバーに変える
void SERCOM2_Handler() //ATSAM D2xシリーズでUARTを定義する際のシリアルハンドラ関数
{
  mySerial.IrqHandler();
}
```

```C++
//UART，I2Cを使う場合，シリアルハンドラ関数が必須です．SPIの場合は不要．
//UARTインスタンスやTwoWireインスタンスの宣言については前回・前々回を参照のこと
//以下は一例です．コピペして使ってください．

/*==============================UART=================================*/
//mySerial：UARTインスタンスの名前
//関数名のSERCOMx_yのxは使用するSERCOMのナンバーに変える．
//yは使用するPADのものだけで良い？(未確認)
Stream *SERIALOUT = &mySerial;
 
void SERCOM0_0_Handler()
{
  mySerial.IrqHandler();
}
void SERCOM0_1_Handler()
{
  mySerial.IrqHandler();
}
void SERCOM0_2_Handler()
{
  mySerial.IrqHandler();
}
void SERCOM0_3_Handler()
{
  mySerial.IrqHandler();
}
/*==============================UART=================================*/


/*===============================I2C=================================*/
//myWire：TwoWireインスタンスの名前
//関数名のSERCOMx_yのxは使用するSERCOMのナンバーに変える．
//I2CはPAD[0]とPAD[1]しか使用できないため，SERCOMｘ_0とSERCOMx_1だけで良い(確認済み)．
extern "C" {
  
Stream *SERIALOUT = &myWire;
 
  void SERCOM4_0_Handler()
  {
    myWire.onService();
  }
  void SERCOM4_1_Handler()
  {
    myWire.onService();
  }
}
/*===============================I2C=================================*/
```

### 補足
>各マイコンのデータシートを見ると，同じシリーズのマイコンでもGPIOの数が違うモデルが有ることやD2xシリーズよりD/E5xシリーズのほうが全体的にGPIO数が多いことがわかります．しかし，Arduino UNOの互換機として製品にされているものは，基本的にD0~D13，A0~A5，POWER系統・SCL・SDAなど決まった数のGPIOしか使用できません．この数のGPIOで足りない場合は，Arduino Mega互換機である「Adafruit Grand Central M4」または，「Arduino Due(Cortex M3シリーズ)」などを使用するか，素直にC言語などで一から開発していくほかありません．

## 今回のまとめ
今回は，Arduinoで開発できるATSAMシリーズのマイコンについて説明しました．ArduinoではマイコンのGPIOを最大限活用することができないものの，便利なライブラリが数多く公開されており，インターネット上にも数多くの情報があるので，迅速なプロトタイピングが必要な人には大変便利なツールだと思います．

また，ArduinoボードやAdafruit・Sparkfunの販売している開発ボードの回路図はもちらん，マイコンをArduino IDEで開発するためのブートローダもすべて公開されているため，自分好みにカスタマイズしたプリント基板などを作ることも簡単にできます．実際，筆者は電気電子回路については素人ですが，個人利用の範囲でプリント基板を作成して使ったりもしています．

以上でSERCOMについての記事は一旦終わりです．