余白 Copyright © 2018-2020 てきーらサンドム


■■■ SAMマイコンの道標(SAMD21) ■■■


端子一覧(SAMD21, 32-64pin) 2020/7/15 追加
 SAMD21E(32pin), SAMD21G(48pin), SAMD21J(64pin)の端子配置を以下に示します。タッチ関係の機能は省略しています。
 
端子機能略号
 E.m   EXTINT[m]     外部割込み
 A.m   ADC/AIN[m]    AD用アナログ入力
 Sn.m  SERCOMn/PAD[m] シリアルI/F(IC不可)
 Sn+m  SERCOMn/PAD[m] IC可能シリアルI/F
 Tn.m  TCCn/WO[m]    制御用途向きタイマ
 Un.m  TCn/WO[m]     基本タイマ
 Co.m  AC/CMP[m]     アナログコンパレータ出力
 Ci.m  AC/AIN[m]      アナログコンパレータ入力
 G.m   GCLK_IO[m]     汎用クロック入出力
 色はSAMC21に対して追加/削除となっている、色はSAMC21に対してチャネル番号違いとなっている
32Pin 48Pin 64Pin 端子名 IO電源系 A:EIC B:A B:Ci B:他 C:S D:S E:U/T F:T G:COM H:Co/G その他
1 1 1 PA00 VDDANA E.0 S1.0 T2.0 XIN32
2 2 2 PA01 VDDANA E.1 S1.1 T2.1 XOUT32
3 3 3 PA02 VDDANA E.2 A.0 VOUT T3.0
4 4 4 PA03 VDDANA E.3 A.1/vrefA T3.1
5 PB04 VDDANA E.4 A.12
6 PB05 VDDANA E.5 A.13
5 7 GNDANA
6 8 VDDANA
9 PB06 VDDANA E.6 A.14
10 PB07 VDDANA E.7 A.15
7 11 PB08 VDDANA E.8 A.2 S4.0 U4.0 T3.6
8 12 PB09 VDDANA E.9 A.3 S4.1 U4.1 T3.7
5 9 13 PA04 VDDANA E.4 A.4/vrefB Ci.0 S0.0 T0.0 T3.2
6 10 14 PA05 VDDANA E.5 A.5 Ci.1 S0.1 T0.1 T3.3
7 11 15 PA06 VDDANA E.6 A.6 Ci.2 S0.2 T1.0 T3.4
8 12 16 PA07 VDDANA E.7 A.7 Ci.3 S0.3 T1.1 T3.5 I2S/SD.0
9 VDDANA
10 GND
11 13 17 PA08 VDDIO NMI A.16 S0+0 S2+0 T0.0 T1.2 I2S/SD.1
12 14 18 PA09 VDDIO E.9 A.17 S0+1 S2+1 T0.1 T1.3 I2S/MCK.0
13 15 19 PA10 VDDIO E.10 A.18 S0.2 S2.2 T1.0 T0.2 I2S/SCK.0 G.4
14 16 20 PA11 VDDIO E.11 A.19 S0.3 S2.3 T1.1 T0.3 I2S/FS.0 G.5
17 21 VDDIO
18 22 GND
19 23 PB10 VDDIO E.10 S4.2 U5.0 T0.4 I2S/MCK.1 G.4
20 24 PB11 VDDIO E.11 S4.3 U5.1 T0.5 I2S/SCK.1 G.5
25 PB12 VDDIO E.12 S4+0 U4.0 T0.6 I2S/FS.1 G.6
26 PB13 VDDIO E.13 S4+1 U4.1 T0.7 G.7
27 PB14 VDDIO E.14 S4.2 U5.0 G.0
28 PB15 VDDIO E.15 S4.3 U5.1 G.1
21 29 PA12 VDDIO E.12 S2+0 S4+0 T2.0 T0.6 Co.0
22 30 PA13 VDDIO E.13 S2+1 S4+1 T2.1 T0.7 Co.1
15 23 31 PA14 VDDIO E.14 S2.2 S4.2 U3.0 T0.4 G.0 XIN
16 24 32 PA15 VDDIO E.15 S2.3 S4.3 U3.1 T0.5 G.1 XOUT
33 GND
34 VDDIO
17 25 35 PA16 VDDIO E.0 S1+0 S3+0 T2.0 T0.6 G.2
18 26 36 PA17 VDDIO E.1 S1+1 S3+1 T2.1 T0.7 G.3
19 27 37 PA18 VDDIO E.2 S1.2 S3.2 U3.0 T0.2 Co.0
20 28 38 PA19 VDDIO E.3 S1.3 S3.3 U3.1 T0.3 I2S/SD.0 Co.1
39 PB16 VDDIO E.0 S5+0 U6.0 T0.4 I2S/SD.1 G.2
40 PB17 VDDIO E.1 S5+1 U6.1 T0.5 I2S/MCK.0 G.3
29 41 PA20 VDDIO E.4 S5.2 S3.2 U7.0 T0.6 I2S/SCK.0 G.4
30 42 PA21 VDDIO E.5 S5.3 S3.3 U7.1 T0.7 I2S/FS.0 G.5
21 31 43 PA22 VDDIO E.6 S3+0 S5+0 U4.0 T0.4 G.6
22 32 44 PA23 VDDIO E.7 S3+1 S5+1 U4.1 T0.5 USB/SOF1kHz G.7
23 33 45 PA24(6) VDDIO E.12 S3.2 S5.2 U5.0 T1.2 USB/DM
24 34 46 PA25(6) VDDIO E.13 S3.3 S5.3 U5.1 T1.3 USB/DP
35 47 GND
36 48 VDDIO
37 49 PB22 VDDIO E.6 S5.2 U7.0 T3.0 G.0
38 50 PB23 VDDIO E.7 S5.3 U7.1 T3.1 G.1
25 39 51 PA27 VDDIO E.15 T3.6 G.0
26 40 52 RESETN RESETN
27 41 53 PA28 VDDIO E.8 T3.7 G.0
28 42 54 GND
29 43 55 VDDCORE
30 44 56 VDDIN
31 45 57 PA30 VDDIO E.10 S1.2 T1.0 T3.4 G.0 SWCLK
32 46 58 PA31 VDDIO E.11 S1.3 T1.1 T3.5 SWDIO
59 PB30 VDDIO E.14 S5+0 T0.0 T1.2
60 PB31 VDDIO E.15 S5+1 T0.1 T1.3
61 PB00 VDDANA E.0 A.8 S5.2 U7.0
62 PB01 VDDANA E.1 A.9 S5.3 U7.1
47 63 PB02 VDDANA E.2 A.10 S5.0 U6.0 T3.2
48 64 PB03 VDDANA E.3 A.11 S5.1 U6.1 T3.3

 
発振回路(SAMD21) 2020/7/18 追加
 SAMD21には、高速発振器4種類、低速発振器3種類を搭載しています。
名称 用途 出力周波数 精度 消費電流[μA] (typ.は25℃時, max.は85℃時)
OSC8M 内部高速発振 1〜8MHz ±1%(25℃, 1.62〜3.63V), -2.5〜+2%(-40〜+85℃, 1.62〜3.63V) 64typ., 96max.
DFLL48M 逓倍可能高速発振 48MHz open loopモード:±1MHz(25℃,粗キャリブレーション後)
closed loopモード:-770〜-400ppm(25℃, 32.768kHz x 1464)
403typ., 453max.
425typ., 482max.(バリエーションA), 403typ., 453max.(バリエーションB/C/D/L)
FDPLL96M 逓倍発振(入力32k〜2MHz) 48〜96MHz 入力に依存 500typ.(48MHz), 1200max.(96MHz)
XOSC 外部水晶発振(高速) 0.4〜32MHz 外部発振子に依存 100max.(4MHz), 172max.(8MHz), 552max.(16MHz), 1200max.(32MHz)。いずれもAGC=ON時
OSC32K 内部低速発振 32.768kHz ±1.5%(Ta25℃,3.3V), -13%〜6%(-40〜85℃, 1.62〜3.63V) 0.67typ., 1.31max.
OSCULP32K 内部超低電力発振 32.768kHz -4.5〜5.5%(Ta25℃,5V), -22%〜16%(-40〜85℃, 1.62〜3.63V) 0.125max.(シミュレーション値)
XOSC32K 外部水晶発振(低速) 32.768kHz 外部発振子に依存 1.22typ., 2.19max.

■OSC8Mの出力周波数は以下になります。リセット時はこの発振器が8分周(= 1MHz)で動作を開始しCPUへクロック供給します。またリセット時に自動的にキャリブレーション・データが設定されます。
   出力周波数 = 8MHz / 2      [ただし n = 0〜3 (OSC8M.PRESC設定値)]

■DFLL48Mの出力周波数は固定です。open loopで使用する場合は、ソフトウエアでキャリブレーションデータを読みとってDFLLVALレジスタのCOARSEビットに設定する必要があります。
   closed loop時の出力周波数 = 入力周波数 x DFLLMUL.MUL設定値      [ただし 出力は48MHz近辺, 入力は0.732〜33kHz範囲]

■FDPLL96Mの逓倍率は、1/16単位で指定できます。整数部をLDR、分数部をLDRFRACとすると、
   出力周波数 = 入力周波数 x (LDR + 1 + LDRFRAC/16)   [XOSC入力時は分周設定で2MHz以下にする]
となります。入力32.768kHzの場合、96MHz発振なら理論誤差0で逓倍できます(LDR = 2928, LDRFRAC = 11)。48MHz発振時は21ppmの理論誤差が出ます(LDR = 1463, LDRFRAC = 14)。

■32k発振端子に注意
 SAMD21のデータシート44.5.3項の最後の方に「サイクル・ジッターを最小限にするためには、隣接端子は極力変化させないように」と言うようなことが書かれています。

■キャリブレーション
 内部発振(DFLL48Mのopen loopモード, OSC32K)を使用する場合は、プログラムでキャリブレーションが必要です。
 (1)DFLL48M
  以下のように設定します(アドレスの意味は別項メモリ・アクセス参照)。
   OSCCTRL->DFLLVALレジスタのCOARSEビット = *(long long*) 0x806020 の[63:58]ビット;

 (2)OSC32K
  以下のように設定します。
   OSC32KCTRL->OSC32KレジスタのCALIBビット = *(long*) 0x806020 の[44:38]ビット;
  SAMD21では未確認ですが、SAMC21で試したところ、キャリブレーション無しでは−3%の誤差だったのが、キャリブレーション後に+0.3%に改善しました。

■各発振器のレジスタ初期値では、オンデマンドが有効になっています。そのままだと、OSC8M以外は供給先が動作しないと発振しません。先に発振確認してから供給する場合は、オンデマンドをオフ(0)にしておく必要があります。
 
クロック生成 GCLK(SAMD21) 2020/7/23 クロック供給先の修正、等
 発振回路等→クロック生成器→各種周辺回路、および周辺回路アクセス用のバス・クロックの順でクロックを供給します(一部除く)。
 SAMD21にはクロック生成器が9個あり、生成器0,2はリセット後も動作します。他の生成器はリセットで停止します。
クロック・ソース選択 クロック生成器分周設定  クロック供給先(代表例)(詳細後述)
設定値 ソース名称 生成器番号 分周範囲 (補足2参照) リセット時  選択可能生成器 対象ブロック
0 XOSC 0 1/1〜1/n〜1/255,
1/2〜1/(2n+1)〜1/512?
注意:速度を落としすぎると
デバッガが二度と反応しなく
なるかも?
OSC8M,
1/1, 動作
生成器0のみ CPU、バス等(PM:パワーマネージャ)
1 クロック入力端子
(ポート)
1 1/1〜1/n〜1/65535,
1/2〜1/(2n+1)〜1/131072
 停止 生成器0〜8(初期値0) 周辺回路ID 0x00:DFLL48Mリファレンス
2 クロック生成器1
の出力
2 1/1〜1/n〜1/31,
1/2〜1/(2n+1)〜1/512?
 OSCULP32K,
1/1, 動作
   : (同上)   :
3 OSCULP32K 3 1/1〜1/n〜1/255,
1/2〜1/(2n+1)〜1/512?
 停止 生成器0〜8(初期値2) 周辺回路ID 0x03:WDT
4 OSC32K 4  停止 生成器0〜8(初期値0) 周辺回路ID 0x04:RTC
5 XOSC32K 5  停止    : (同上)   :
6 OSC8M 6  停止 生成器0〜8(初期値0) 周辺回路ID 0x1A:TCC0, TCC1
7 DFLL48M 7  停止    : (同上)   :
8 FDPLL or
DPLL96M(注3)
8  停止

注意1:CPUから周辺回路をアクセスするためのバスクロックの供給/停止の選択はPMにおいて行います(対象周辺回路ごと)。詳細後述。
注意2:CPUから周辺回路のレジスタをアクセスする場合に同期化処理が必要になる場合があります(詳細後述)
注意3:バリエーションA(SAMD21xxxA)のGCLK_GENCTRL_SRC_のみDPLL96Mの名称でヘッダ定義、他のレジスタおよびバリエーションD(SAMD21xxxD)ではFDPLLの名称でヘッダ定義してます。
補足1:PM(パワーマネージャ)内で、さらに1/1〜1/128分周が可能です。
補足2:分周範囲はGENCTRLn.DIVSELの設定により1/nか1/(2n+1)が選択可能ですが、SAMC2xでは1/(2n+1)の方はマニュアルに記載のない上限がありました。SAMD21では上限未確認です。またSAMC21で生成器0を4MHz/512=7.8kHzに設定したらデバッガが反応しなくなりました(PICkit4, Snapとも)。

■パス・クロック供給(SAMD21)
 CPUから周辺回路をアクセスするには、パワー・マネージャ(PM)のレジスタ設定が必要です。ただし一部の周辺回路はデフォルトでイネーブルになっています(下表*印)。
 なお下表のAxx.yyは実際には、PM->AxxMASK.bit.yyとコーディングします。 
bit 対象 bit 対象 bit 対象
AHB.HPB0 *周辺バス・ブリッジA APBB.PAC1 *周辺アクセス保護 APBC.TCC1 制御向きタイマ1
AHB.HPB1 *周辺バス・ブリッジB APBB.DSU *デバイス・サービス・ユニット APBC.TCC2 制御向きタイマ2
AHB.HPB2 *周辺バス・ブリッジC APBB.NVMCTRL *フラッシュ制御 APBC.TC3 汎用タイマ3
AHB.DSU *デバイス・サービス・ユニット APBB.PORT *ポート APBC.TC4 汎用タイマ4
AHB.NVMCTRL *フラッシュ制御 APBB.DMAC *DMAC APBC.TC5 汎用タイマ5
AHB.DMAC *DMAC APBB.USB *USB APBC.TC6 汎用タイマ6
AHB.USB *USB APBC.PAC2 周辺アクセス保護 APBC.TC7 汎用タイマ7
APBA.PAC0 *周辺アクセス保護 APBC.EVSYS イベント制御 APBC.ADC *AD変換
APBA.PM *パワー管理 APBC.SERCOM0 シリアル通信0 APBC.AC コンパレータ
APBA.SYSCTRL *システム制御 APBC.SERCOM1 シリアル通信1 APBC.DAC DA変換
APBA.GCLK *クロック生成 APBC.SERCOM2 シリアル通信2 APBC.PTC タッチ制御
APBA.WDT *ウォッチドッグ APBC.SERCOM3 シリアル通信3 APBC.I2S I2S
APBA.RTC *時計 APBC.SERCOM4 シリアル通信4 APBC.AC1 AC1
APBA.EIC *外部割込制御 APBC.SERCOM5 シリアル通信5 APBC.TCC3 制御向きタイマ3
APBC.TCC0 制御向きタイマ0


■クロック供給先一覧(SAMD21)
ch番号(定義名) 供給先 ch番号(定義名) 供給先 ch番号(定義名) 供給先
0 DFLL48Mリファレンス入力 13 イベント・チャネル6 26 制御向きタイマ0,1
1 FDPLL96Mリファレンス入力 14 イベント・チャネル7 27 TCC2, TC3
2 FDPLL96M 32kHzクロック 15 イベント・チャネル8 28 汎用タイマ4,5
3 WDT 16 イベント・チャネル9 29 汎用タイマ6,7
4 RTC 17 イベント・チャネル10 30 AD変換
5 EIC 18 イベント・チャネル11 31 コンパレータ
6 USB 19 シリアル通信の低速用(*) 32 コンパレータ
7 イベント・チャネル0 20 シリアル通信0(コア) 33 DA変換
8 イベント・チャネル1 21 シリアル通信1(コア) 34 タッチ制御
9 イベント・チャネル2 22 シリアル通信2(コア) 35 I2S_0
10 イベント・チャネル3 23 シリアル通信3(コア) 36 I2S_1
11 イベント・チャネル4 24 シリアル通信4(コア) 37 制御向きタイマ3
12 イベント・チャネル5 25 シリアル通信5(コア)
*:シリアル通信の低速用は、I2Cの特定機能で使用(例えばSMBusタイミング)。

■レジスタ・アクセスの同期化処理
 周辺回路の一部のレジスタは、CPUバスからアクセスする場合に同期化処理が必要になります(CPUバスと周辺クロックの違いにより)。
 (1)書き込み時
   各周辺レジスタの中でレジスタのPropertyにWrite-Syncronizedと書かれているものは、
  同期待ち(Synchronization Busy)レジスタの対応フラグが1の間は「書き換え中」なのでアクセスしてはいけません。
   例えば、SERCOM USARTのCTRLBレジスタの中にRXEN(受信許可)、TXEN(送信許可)のビットがありますが、
  これをビット・アクセスで連続して書き換えるのはNGです。一般的には、ビットアクセスではなく、ワードアクセスでRXEN,TXENを同時に書き換えればよいのですが、
  何かの事情でどうしても1ビットづつ書き換えたい場合は、ビジーフラグが0になってから次のアクセスします。
     例(この例は例外だが、他のレジスタでは必要になる場合があるかも):
        SERCOM1->USART.CTRLB.bit.RXEN = 1;
        while (SERCOM1->USART.SYNCBUSY.bit.CTRLB);
        SERCOM1->USART.CTRLB.bit.TXEN = 1;

 (2)読み出し時
   レジスタのPropertyにRead-Synchronizedと書かれているものは、このレジスタの読み出しに先だって「読み出し要求(作法は周辺回路による)」を行って、
  同期待ち(Synchronization Busy)レジスタの対応フラグが0に戻ってから読み出しを行います。
     例(カウンタ値の読み出し):
        TC3->COUNT16.READREQ.reg = 0x8010;  //カウント値の読み出し要求.
        while (TC3->COUNT16.STATUS.bit.SYNCBUSY);
        (格納先) = TC3->COUNT16.COUNT.reg;
 
I2C(SAMC2x, D21, D51, E5x) 2022/5/20 更新
 SERCOM(シリアル・コミュニケーション・インタフェース)をI2Cマスタとして使用する場合について以下記載します。なお、端子SERCOMn/PAD[m]をSn+mと略記します。

■端子
(1)SDA:Sn+0端子
(2)SCL:Sn+1端子

■ボーレート設定
 I2Cの規格では、SCL(クロック)のHレベル期間とLレベル期間の比率を1:2にするように要求されているようです。そのため、ボーレートレジスタBAUDの中はHレベル期間用のBAUDビットとLレベル期間用のBAUDLOWビットに分かれています(SCLクロック1MHz以下の場合)。
   設定値BAUD.BAUD = SERCOM供給クロック / SCL最大クロック周波数 / 3 - 5   ・・・/3は比率1:2にするため、-5はSERCOM I2C独自の補正値
   設定値BAUD.BAUDLOW = SERCOM供給クロック / SCL最大クロック周波数 - BAUD.BAUD - 10   ・・・ -10はSERCOM I2C独自の補正値(Hレベル分-5, Lレベル分-5)
   実クロック周波数 = 供給クロック / (BAUD.BAUD + BAUD.BAUDLOW + 10 + 立ち上がりクロック数)
 ここで、立ち上がりクロック数とは、SCLがLからHに立ち上がるまでの時間を供給クロック周波数で換算したもので、立ち上がり時間[ns] x 供給クロック[MHz] / 1000で計算できます。実クロック周波数を規格限界まで上げたい場合は、立ち上がりクロック数をBAUDLOWから差し引いておけばよいのですが、一般的には立ち上がり時間が明確でない場合が多いので無理せず補正しない方が良いでしょう。

■使用上の留意点
(1)初期設定後にバスステートをアイドルに設定
  各種クロック設定、ポート設定、SERCOMのCTRLAレジスタ、BAUDレジスタの設定後、CTLRA.ENABLEビットを立てることにより動作を開始します。UARTやSPIは、この状態ですぐに送信ができたのですが、I2Cの場合はバスステート(STATUSレジスタのBUSSTATEビット)がUNKNOWNのままで動作しません。STATUS.BUSSTATEに0x01(アイドル状態)を設定する必要があります(タイムアウト設定していない場合)。
(2)最初にSTOPコンディションの生成が必要か?
 電源ONからであればSDA,SCLともHの状態からスタートしますが、ウオッチドッグによるリスタートなどの場合は通信相手がACK応答状態のままになることがあります。このような場合の対策としてBUSSTATE設定後にSTOPコンディションの生成(CTRLB.CMDに0x03設定)が望ましいと思われます。
(3)データ書き込み
 I2Cアドレスおよび書き込み指示をADDRレジスタに書き込むと自動的に送信が開始され、終了するとINTFLAG.MBが立ちます(INTENSETしている場合)。以降、1バイトのデータをDATAレジスタに書き込めば自動的に送信し、終了する都度にINTFLAG.MBが立ちます。なお、MBフラグはADDRレジスタやDATAレジスタの書き込みで自動クリアされます。
(4)データ読み出し
 I2Cアドレスおよび読み出し指示をADDRレジスタに書き込むと自動的に送信が開始されます。さらに自動的にデータを1バイト読み取り終えるとINTFLAG.SBが立ちますので、DATAレジスタに格納された受信データを読み取ります。引き続き読み出すデータがあればCTRLB.CMDに0x02を書き込み、データ受信完了を示すINTFLAG.SBが立ったらDATAレジスタから受信データを読みとります。
 ACK/NACKのどちらを返すかは、CTRLB.ACTACKの設定で決まります。ACTACK=0ならACKとなります。
 ACK/NACKを相手に返すタイミングは通常モード(CTRLB.SMEN = 0)かスマートモード(CTRLB.SMEN = 1)かで異なります。通常モードの場合、CTRLB.CMDに書込み後に返します。スマートモードではDATAレジスタ読取り直後に返します。通常モードの場合、CTRLB.CMDとCTRLB.ACTACKを同時に設定することができるので、例えばEEPROMの連続リードのように続けてリードが必要な場合はACTACK=0 (ACK), CMD=2(リード)を設定し、最後のデータ受信後はACTACK=1 (NACK), CMD=3(ストップ)を設定するというような制御ができます。

 
USB(SAMD21) 2020/8/13 更新
 SAMD21のUSBは、デバイスおよび組込みホストの両方をサポートしています。自力でUSBスタックを作る気力はないので、Harmony v3を入れました。自宅には光回線引いてますが、Harmony v3本体全部で18GBもあり、導入に相当時間がかかりました。
 英語の資料だけでは大変なので、Harmony v3の解説が載っている「SAMファミリ活用ガイドブック」も買って見ています。やはり日本語は楽ですね。HarmonyプロジェクトのUSBドライバをXC32 Standaloneプロジェクトに移植する方法については【USBドライバをHarmonyから移植】を参照願います。