IchigoJam で UART のパリティを設定する

[IchigoJam](https://ichigojam.net/) BASIC では、UARTの通信速度を設定する命令はあるが、パリティを設定する命令はなさそうである。
そこで、本記事では、マシン語を用いてUARTのパリティを設定する方法を紹介する。

※IchigoJamはjig.jpの登録商標です。

# 各機種ごとの仕様

## 従来型

従来型の IchigoJam には、LPC1114FN28/102 や LPC1114FDH28/102 が使用されている。
これらのマイコンの仕様は、[UM10398](https://community.nxp.com/pwmxy87654/attachments/pwmxy87654/lpc/28119/2/UM10398.pdf) に掲載されている。
これらのマイコンには、UARTが1個だけ搭載されている。

アドレス `0x4000800C` にあるレジスタ `U0LCR` の以下のビットを設定することで、UART のパリティを設定できる。

|ビット|設定値|
|:-:|---|
|3|0：パリティビットなし<br>1：パリティビットあり|
|4～5|0：奇数パリティ<br>1：偶数パリティ<br>2：パリティビットを常に1にする<br>3：パリティビットを常に0にする|

## IchigoJam R

IchigoJam R には、GD32VF103CBT6 が使用されている。
このマイコンのデータシートは、以下のページから入手できる。
[GD32VF103CBT6-MCUs Product Selector-GigaDevice.com](https://www.gigadevice.com/product/mcu/mcus-product-selector/gd32vf103cbt6)
さらに、
[IchigoJam Rβ x 無線USBキーボード、ピン配置とセーブデータの読み書き方法公開](https://fukuno.jig.jp/3104)
を参照すると、IchigoJam R の RXD・TXD として使用されるのは USART0 であることがわかる。

アドレス `0x4001380C` にあるレジスタ `USART_CTL0` の以下のビットを設定することで、UART (USART0) のパリティを設定できる。

|ビット|設定値|
|:-:|---|
|9|0：偶数パリティ<br>1：奇数パリティ|
|10|0：パリティビットなし<br>1：パリティビットあり|
|12|0：データとパリティビット(あれば)を合わせて8ビット<br>1：データとパリティビット(あれば)を合わせて9ビット|

## IchigoJam P

IchigoJam P には、Raspberry Pi Pico (RP2040) が使用されている。
製品ページからデータシートを入手できる。
[Buy a Raspberry Pi Pico – Raspberry Pi](https://www.raspberrypi.com/products/raspberry-pi-pico/)
さらに、[以前の調査](https://qiita.com/mikecat_mixc/items/65e234f73d64913a611a#%E5%85%A5%E5%87%BA%E5%8A%9B%E3%83%9D%E3%83%BC%E3%83%88%E3%81%AE%E5%AF%BE%E5%BF%9C%E9%96%A2%E4%BF%82)の結果を参照すると、IchigoJam P の RXD・TXD として使用されるのは UART0 であることがわかる。

アドレス `0x4003402C` にあるレジスタ `UARTLCR_H` の以下のビットを設定することで、UART (UART0) のパリティを設定できる。

|ビット|設定値|
|:-:|---|
|1|0：パリティビットなし<br>1：パリティビットあり|
|2|0：奇数パリティ or パリティビットを常に1にする<br>1：偶数パリティ or パリティビットを常に0にする|
|7|0：奇数/偶数パリティを用いる<br>1：パリティビットの値を固定する|

# 機種の判別方法

従来型・IchigoJam P と IchigoJam R は、命令セットの違いにより判別できる。
[これまでの(LPC1114を用いた) IchigoJam と IchigoJam R 両対応のマシン語 #IchigoJam - Qiita](https://qiita.com/mikecat_mixc/items/5c14111e8f144d16b4fa)

従来型と IchigoJam P は、`CPUID` レジスタ (`0xE000ED00`) の値により判別できる。
[新しい仲間 IchigoJam P をいじってみる #IchigoJam - Qiita](https://qiita.com/mikecat_mixc/items/65e234f73d64913a611a#%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E3%81%AE%E5%88%A4%E5%88%A5)

# パリティの設定を行うコード

このコードは、[CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/deed.ja) でライセンスする。

`USR` 関数の第2引数に基づいて、以下のようにパリティを設定する。

* 0：パリティビットなし
* 1：奇数パリティ
* 2：偶数パリティ

```text:設定用マシン語
	IF M0 GOTO @M0
MODE RV32C
	' IchigoJam R
	' レジスタアドレス #4001380C
	' 12ビットの数を足す際、符号拡張されることに注意
	R15 = #40014000
	R15 = R15 + #80C
	R14 = [R15 + 0]L
	' ビット 9・10・12 を 0 にする
	R13 = `1011
	R13 <<= 9
	R13 = R13 ^ #FFF
	R14 &= R13
	' パリティビットなしに設定する場合、値の書き換えを終了する
	IF !R10 GOTO @R_END
	' ビット 10・12 を 1 にする
	R13 = `101
	R13 <<= 10
	R14 |= R13
	' 奇数パリティなら、ビット 9 を 1 にする
	R11 = R10 + -1
	IF R11 GOTO @R_END
	R14 = R14 | #200
@R_END
	' 書き換えた値をレジスタに書き込む
	[R15 + 0]L = R14
	RET
MODE M0
@M0
	R1 = [@CPUID_ADDR]L
	R1 = [R1]L
	R1 = R1 << 20
	R1 = R1 >> 28
	R1 - 6
	IF 0 GOTO @P
	' 従来型
	R3 = [@LEGACY_REG_ADDR]L
	R2 = [R3]L
	' ビット 3・4・5 を 0 にする
	R1 = `111000
	BIC R2, R1
	' パリティビットなしに設定する場合、値の書き換えを終了する
	R0 - 0
	IF 0 GOTO @M0_END
	' ビット 3 を 1 にする
	R2 += `1000
	' 奇数パリティでないなら、ビット 4 を 1 にする
	R0 - 1
	IF 0 GOTO @M0_END
	R2 += `10000
	GOTO @M0_END
@P
	' IchigoJam P
	R3 = [@P_REG_ADDR]L
	R2 = [R3]L
	' ビット 1・2・7 を 0 にする
	R1 = `10000110
	BIC R2, R1
	' パリティビットなしに設定する場合、値の書き換えを終了する
	R0 - 0
	IF 0 GOTO @M0_END
	' ビット 1 を 1 にする
	R2 += `10
	' 奇数パリティでないなら、ビット 2 を 1 にする
	R0 - 1
	IF 0 GOTO @M0_END
	R2 += `100
	' 書き換えた値をレジスタに書き込む (従来型・IchigoJam P 共通)
@M0_END
	[R3]L = R2
	RET
ALIGN 4, 0, 0
@CPUID_ADDR
	DATAL #E000ED00
@LEGACY_REG_ADDR
	DATAL #4000800C
@P_REG_ADDR
	DATAL #4003402C
```

```text:デモプログラム
10 ' ﾊﾟﾘﾃｨ ｾｯﾃｲ ﾃﾞﾓ
20 POKE#700,183,47,20,224,183,71,1,64,147,135,199,128,152,67,173,70,166,6,147,198,246,255,117,143,9,201,149,70,170,6,85,143,147,5,245,255,153,225,19,103,7,32,152,195,130,128,14,73,9,104,9,5,9,15
30 POKE#736,6,41,10,208,12,75,26,104,56,33,138,67,0,40,14,208,8,50,1,40,11,208,16,50,9,224,7,75,26,104,134,33,138,67,0,40,3,208,2,50,1,40,0,208,4,50,26,96,112,71,0,237,0,224,12,128,0,64,44,64,3,64
40 ' ｷｽｳ ﾊﾟﾘﾃｨ
50 X=USR(#700,1)
60 ?"23";
70 ' ｸﾞｳｽｳ ﾊﾟﾘﾃｨ
80 X=USR(#700,2)
90 ?"23";
100 ' ﾊﾟﾘﾃｨ ﾋﾞｯﾄ ﾅｼ
110 X=USR(#700,0)
120 ?"23";
```

# デモプログラムの実行結果

プログラムの実行前に

```text
OK2
```

を実行し、実行完了時に「OK」を出力しない設定にした上で実行を行った。

## IchigoJam Q (従来型)

デフォルトの 115,200 bps では、送信と送信の間が開きすぎてしまい、結果が見にくくなってしまう。
そこで、`OK2` に加えて

```text
BPS-384
```

を実行し、通信速度を 38,400 bps に設定して実行を行った。
その結果、以下の出力が得られた。

![IchigoJam Q での実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/18e2f9cb-d2f6-4280-a8c7-6a00ff544954.png)

設定に従い、奇数パリティ・偶数パリティ・パリティビットなしでそれぞれ出力されている。
最後のブロックでは、パリティビットが無いにもかかわらず、デコーダはパリティビットがあると仮定して処理をしているためデータの表示がズレてしまっているが、出力されている信号そのものに問題はなさそうだ。

## IchigoJam R

通信速度はデフォルト (115,200 bps) で実行を行った。
その結果、以下の出力が得られた。

![IchigoJam R での実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/6b7ba762-716d-4a8f-9d37-8d9ee93e2fe5.png)

設定に従い、奇数パリティ・偶数パリティ・パリティビットなしでそれぞれ出力されている。

## IchigoJam P

通信速度はデフォルト (115,200 bps) で実行を行った。
その結果、以下の出力が得られた。

![IchigoJam P での実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/f8aecf3c-0903-4905-a63a-4161e0bac7cf.png)

奇数パリティでの出力はうまくいっているが、偶数パリティで出力するはずの 0x33 のパリティビットが出力されていない。
これは、データの送信を終える前にパリティビットなしの設定に切り替えてしまったからであると予想できる。
そこで、以下のコードを追加し、パリティビットなしに切り替える前に少し待つようにした。

```text
95 WAIT -5
```

すると、以下の出力が得られた。

![IchigoJam P での実行結果 (待ち追加)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/7ab6ab02-5ca1-4b5f-9f6e-a4170a8fe4c4.png)

設定に従い、奇数パリティ・偶数パリティ・パリティビットなしでそれぞれ出力されている。

今回は省略するが、マシン語のコードで「パリティビットの設定を変更する前に、今バッファにあるデータの送信が全て完了するまで待つ」処理を入れることでも、対策ができると考えられる。
ただし、もちろんこの処理を入れるとその分コードが長くなるので、頻繁に設定を切り替えるのでなければ不要だろう。

# まとめ

* IchigoJam の各機種において、UART のパリティを設定する方法をそれぞれ調査した
* それを用いて、UART のパリティを設定するプログラムを実装した
* それを実行し、実際に UART のパリティを設定できることを確認した