UART

# はじめに
UARTの設定諸々についての記述．マイコンボードはGR-CITRUSとする．ハードウェアマニュアルの参考先はHM ＊.＊.＊と表記する（例：HM 3.3.4ならばハードウェアマニュアルの3.3.4節を参考）．

資料（必需品）
・ [RX63Nグループ、RX631グループ ユーザーズマニュアル](https://www.marutsu.co.jp/contents/shop/marutsu/datasheet/R5F563.pdf)
・ [GR-CITRUS回路図](https://www.renesas.com/jp/ja/doc/gr/gr-citrus/citrus-1.0.pdf)

# UART設定
UARTのための初期化と1byte送信・受信する関数の作成を行う．

### 初期化関数
流れ
1. 端子機能の設定
2. SCRの設定
3. データ形式の設定
4. ビットレートの設定
5. 通信開始

```c:"hwsetup.c"
void SCI0_init(void);

void HardwareSetup(void)
{
    SCI0_init();
}
```

```c:
/*=================================
 * 関数名 : SCI0_init
 * 機能 : SCI0の初期化
 * 引数 : なし
 * 戻り値 : なし
 * 備考 :通信速度 115200bps
 * ===============================*/
void SCI0_init(void)
{
	/*=== プロテクト解除 ===*/
    SYSTEM.PRCR.WORD = 0xA502;
    /*=== SCI0を有効化 ===*/
    MSTP(SCI0) = 0;
    /*=== プロテクト ===*/
    SYSTEM.PRCR.WORD = 0xA500;
    /*=== 端子機能の有効化 ===*/
    PORT2.PMR.BIT.B0 = 1;
    PORT2.PMR.BIT.B1 = 1;
    /*=== ピン機能設定 プロテクト解除===*/
    MPC.PWPR.BIT.B0WI = 0;
    MPC.PWPR.BIT.PFSWE = 1;
    /*=== ピン機能設定 ===
    * P20 > TXD0
    * P21 > RXD0
    * ================*/
    MPC.P20PFS.BIT.PSEL = 0x0A;
    MPC.P21PFS.BIT.PSEL = 0x0A;
    /*=== ピン機能設定 プロテクト===*/
    MPC.PWPR.BIT.PFSWE = 0;
    MPC.PWPR.BIT.B0WI = 1;
    /*=== SCR設定 割り込み禁止 SCK未使用 ===*/
    SCI0.SCR.BIT.TEIE = 0;
    SCI0.SCR.BIT.MPIE = 0;
    SCI0.SCR.BIT.RE = 0;
    SCI0.SCR.BIT.TE = 0;
    SCI0.SCR.BIT.RIE = 0;
    SCI0.SCR.BIT.TIE = 0;
    SCI0.SCR.BIT.CKE = 0;
    /*=== シリアルインターフェース ===*/
    SCI0.SIMR1.BIT.IICM = 0;
    /*=== クロックセレクト > 極性反転なし 遅れなし ===*/
    SCI0.SPMR.BIT.CKPH = 0;
    SCI0.SPMR.BIT.CKPOL = 0;
    /*=== 通信フォーマット設定 ===
     * クロック : PCLK
     * ストップビット : 1bit
     * パリティ : なし
     * データ長 : 8bit
     * 調歩同期式
     * ====================*/
    SCI0.SMR.BIT.CKS = 0;
    SCI0.SMR.BIT.MP = 0;
    SCI0.SMR.BIT.STOP = 0;
    SCI0.SMR.BIT.PM = 0;
    SCI0.SMR.BIT.PE = 0;
    SCI0.SMR.BIT.CHR = 0;
    SCI0.SMR.BIT.CM = 0;
    /*=== 通信ビットレート設定 ===
  	 * 転送速度 115200bps
   	 * ===============*/
    SCI0.SEMR.BIT.ABCS = 0;
    SCI0.BRR = 12;
    /*=== 通信開始 ===*/
    SCI0.SCR.BIT.RE = 1;
    SCI0.SCR.BIT.TE = 1;
}
```

### 1byte送信・受信する関数

```c:"sci.h"
void SCI0_write(char data);
char SCI0_read(void);
```

```c:"sci.c"
/*=================================
 * 関数名 : SCI0_write
 * 機能 : UART(SCI0)で1byte送信する
 * 引数 : なし
 * 戻り値 : なし
 * 備考 :
 * ===============================*/
void SCI0_write(char data)
{
	/*=== 送信完了待ち ===*/
    while(!SCI0.SSR.BIT.TEND);
    /*=== 送信 ===*/
    SCI0.TDR = data;
    /*=== フラグクリア ===*/
    SCI0.SSR.BIT.TEND = 0;
}
```
```c:
/*=================================
 * 関数名 : SCI0_read
 * 機能 : UART(SCI0)で1byte受信する
 * 引数 : なし
 * 戻り値 : 受信したデータ
 * 備考 :
 * ===============================*/
char SCI0_read(void){
    char data;
    /*=== 受信 ===*/
    data = SCI0.RDR;
    return data;
}
```

```c:"main.c"
#include"iodefine.h"
#include"icu_cmt.h"
#include"sci.h"

#define LED PORTA.PODR.BIT.B0
#define LED_ON 1
#define LED_OFF 0

void main(void)
{

	while(1)
	{

		if(SCI0_read() == 'a')
		{
			LED = LED_ON;
			SCI0_write('O');
			SCI0_write('N');
		}
		if(SCI0_read() == 'f')
		{
			LED = LED_OFF;
		}
	}

}
```

### 詳細

#### 初期化関数

##### 1. 端子機能の設定
```
SYSTEM.PRCR.WORD = 0xA502;
```
**プロテクト解除**
HM 13.1.1より，保護するレジスタへの書き込み許可を選択する．`WORD`で一括で設定している．`PRCR`は16bit構成でb15-8にはPRCキーコードビット`A5`を入れる．b7-b0が`2`で動作モード、消費電力低減機能、ソフトウェアリセット関連レジスタへの書き込み許可となる．

```
MSTP(SCI0) = 0;
```
**モジュールストップ解除**
HM 11.4より，レジスタの読み出し書き込みができる状態にする必要がある．`=0`で解除となる．

```
SYSTEM.PRCR.WORD = 0xA500;
```
**プロテクト**
HM 13.1.1より，保護するレジスタへの書き込みを禁止する．

```
PORT2.PMR.BIT.B0 = 1;
PORT2.PMR.BIT.B1 = 1;
```
**端子機能の有効化**
HM 1.5 表1.10より，必要な機能が備わっている端子を選定する．HM 21.3.4より，`=1`で端子機能を有効化する．

```
MPC.PWPR.BIT.B0WI = 0;
MPC.PWPR.BIT.PFSWE = 1;
```
**ピン機能設定 プロテクト解除**
HM 22.2.1より，初めに`B0WI = 0`でPFSWEレジスタへの書き込みを許可する．次に，`PFSWE = 1`でPFSレジスタへの書き込みを許可する．許可順番は必ず守る．

```
MPC.P20PFS.BIT.PSEL = 0x0A;
MPC.P21PFS.BIT.PSEL = 0x0A;
```
**ピン機能設定**
HM 22.2.3より，周辺機能を設定する．ここでは，P20をTXD0，P21をRXD0として設定している．レジスタへの値は表で指定されたものを書き込む．

```
MPC.PWPR.BIT.PFSWE = 0;
MPC.PWPR.BIT.B0WI = 1;
```
**ピン機能設定 プロテクト**
HM 22.2.1より，順次プロテクトする．プロテクト順番は必ず守る．

##### 2. SCRの設定
```c
SCI0.SCR.BIT.TEIE = 0;
SCI0.SCR.BIT.MPIE = 0;
SCI0.SCR.BIT.RE = 0;
SCI0.SCR.BIT.TE = 0;
SCI0.SCR.BIT.RIE = 0;
SCI0.SCR.BIT.TIE = 0;
SCI0.SCR.BIT.CKE = 0;
```
HM 35.2.6より，割り込みやシリアル送受信動作の禁止を行う．
`CKE = 0`で、SCKn端子は入出力ポートとして使用する．

##### 3. データ形式の設定
```c
SCI0.SIMR1.BIT.IICM = 0;
```
HM 35.2.12より，シリアルインタフェースモード（調歩同期式）を選択する．

```c
SCI0.SPMR.BIT.CKPH = 0;
SCI0.SPMR.BIT.CKPOL = 0;
```
HM 35.2.16より，クロック選択はUARTの場合は'=0'にする．

```c
    /*=== 通信フォーマット設定 ===
     * クロック : PCLK
     * ストップビット : 1bit
     * パリティ : なし
     * データ長 : 8bit
     * 調歩同期式
     * ====================*/
    SCI0.SMR.BIT.CKS = 0;
    SCI0.SMR.BIT.MP = 0;
    SCI0.SMR.BIT.STOP = 0;
    SCI0.SMR.BIT.PM = 0;
    SCI0.SMR.BIT.PE = 0;
    SCI0.SMR.BIT.CHR = 0;
    SCI0.SMR.BIT.CM = 0;
```
HM 35.2.5より，通信フォーマットの設定をする．ここで設定した通信フォーマットを通信先とそろえる必要がある．
**CKSレジスタ**
PCLKに対する分周を決定する．次のビットレート設定との兼ね合いで調整する．
**MPレジスタ**
マルチプロセッサ通信機能を選択する．
**STOPレジスタ**
ストップビットを1bitまたは2bitか選択する．`=0`で1bitのストップビットとなる．調歩同期式モードのみ有効．
**PMレジスタ**
パリティモードビットのタイミングを設定する．調歩同期式モードで、PEビット＝1のときのみ有効．
**PEレジスタ**
パリティビットの有無を選択する．`=0`でパリティビットなし．
**CHRレジスタ**
データ長を選択する．`=0`で8bitとなる．
**CMレジスタ**
通信方法の選択をする．`=0`で調歩同期式で動作する．

##### 4. ビットレートの設定
```c
SCI0.SEMR.BIT.ABCS = 0;
SCI0.BRR = 12;
```
HM 35.1.10より，調歩同期基本クロックを設定する．
HM 35.2.9より，転送速度を設定する．表35.8の計算式に従って所望の転送速度になるようにBRRレジスタの値を入れる．この時，BRRレジスタが0～255の範囲に収まるようにABCSレジスタやCKSレジスタの値を調整する．
設定例
115200bps > CKS = 0,ABCS = 0, BRR = 12
9600bps > CKS = 0,ABCS = 0, BRR = 155
2400bps > CKS = 2, ABCS = 0, BRR = 38


##### 5. 通信開始
```c
    SCI0.SCR.BIT.RE = 1;
    SCI0.SCR.BIT.TE = 1;
```
HM 35.2.6より，"=1"で送信・受信動作を開始する．

#### 送信関数
```c
while(!SCI0.SSR.BIT.TEND);
```
HM 35.2.7より，"TEND =1"で送信が終了したことを表示する．送信中にTDRレジスタへの書き込みを防ぐ．

```c
SCI0.TDR = data;
```
HM 35.2.3 & 35.2.4より，送信するデータをTDRレジスタに格納する．TDRレジスタに格納されたデータはTSRレジスタへ移されてから送信される．

```c
SCI0.SSR.BIT.TEND = 0;
```
HM 35.2.7より，TENDフラグのクリアを行う．

#### 受信関数
```c
data = SCI0.RDR;
```
HM 35.2.2より，RDRレジスタは受信したデータが格納されるレジスタである．このレジスタをリードしてデータを読み込む．

### Tera Term

シリアル接続でＰＣとマイコンと送受信できる．接続には秋月で買えるＵＳＢシリアル変換モジュールが必要．COMポート，通信速度等のミスによる通信不良や文字化けに注意．通信不良の原因としては以下のものがあった．

- クロックの設定ミス．発振子の周波数を勘違いした状態で計算していた．
- TeraTermの通信速度の設定ミス．
- シリアルポートが接続できていなかった．
- デバックモード設定をしていないのに16進法で文字を送信していた（文字コード範囲外の16進数を送っていた）ので文字化けしているように見えた．

16進法で情報をやり取りすることも多いので表示可能になるように設定しておくと便利．Tera termで16進数表示するためには，[このサイト](http://shuzo-kino.hateblo.jp/entry/20111027/1319682490)を参考にして，Debug=onとする．

# 参考文献

- 東芝MCUの7種類のシリアルインタフェース https://toshiba.semicon-storage.com/jp/design-support/e-learning/mcupark/village/serial-interface-2.html
- RX631開発 UART - CCWO https://ccwo.hatenablog.jp/entry/2016/08/18/013936
- Tera termで16進数表示 http://shuzo-kino.hateblo.jp/entry/20111027/1319682490
- https://www.renesas.com/jp/ja/doc/products/mpumcu/tu/002/tnrxa138aj.pdf