Raspberry Pi, Jetson Nano向けオーディオ入出力ボードの作成(Jetson Nanoへの移植トラブル編)

[前回](https://qiita.com/kmitsu76/items/07b0bea26ad996e16b30)作成したコーデックボードをJetson Nanoへ接続して音出しをしていきたい。
##Jetson NanoでのI2Sデバイスの接続について

[Jetson Nanoの40ピンコネクター](https://www.element14.com/community/community/designcenter/single-board-computers/blog/2019/05/21/nvidia-jetson-nano-developer-kit-pinout-and-diagrams)はRaspberry pi互換となっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/c61b7610-74c9-3795-adf3-8fdc0c0faedf.png)

接続のイメージは下記の通りとなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/9a0ad751-b928-4bdf-a500-90bb7c943f26.png)

Raspberry piの際に設定したように、BCKとLRCKをコーデックボードからもらう設定を行う。
Jetson Nanoの場合は下記のようにする。

```
$ amixer -c tegrasndt210ref cget name="I2S4 codec master mode"
numid=614,iface=MIXER,name='I2S4 codec master mode'
  ; type=ENUMERATED,access=rw------,values=1,items=5
  ; Item #0 'None'
  ; Item #1 'cbm-cfm'
  ; Item #2 'cbs-cfm'
  ; Item #3 'cbm-cfs'
  ; Item #4 'cbs-cfs'
  : values=4

$ amixer -c tegrasndt210ref cset name="I2S4 codec master mode" 1
numid=614,iface=MIXER,name='I2S4 codec master mode'
  ; type=ENUMERATED,access=rw------,values=1,items=5
  ; Item #0 'None'
  ; Item #1 'cbm-cfm'
  ; Item #2 'cbs-cfm'
  ; Item #3 'cbm-cfs'
  ; Item #4 'cbs-cfs'
  : values=1
```

もしくは、alsamixerで下記のように設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/ff9eb34b-5c3b-fdab-d4bd-a16795221d11.png)

これでコーデックボードとJetson Nanoの通信方向の設定は終わり。

##I2Sを40pinヘッダーへアサインする設定（現在は簡略化）
Jetson NanoはALSAからはRT565xドライバーが認識され、その配下で自由に配線を変更できる[Tegra ASOC Driver](https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-271/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide/l4t_asoc_driver.html#wwpID0E0XS0HA)というものにつながるらしい。
AMX、ADX、TDM等マルチチャンネルを扱うための設定も存在するようだ。


標準の状態では上記4つのpinはGPIOに割り当てられていて、I2Sをアサインするために、レジスタを変更する必要があるらしい。
https://devtalk.nvidia.com/default/topic/1049674/jetson-nano/audio-i2s-on-40-pin-connector/

標準では下記の表示のところ

```
$ sudo grep "Name:\|J:\|BB:" /sys/kernel/debug/tegra_gpio                                                                                                                                                                
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
 J: 2:1 f0 00 00 00 00 00 000000
BB: 6:3 01 00 00 00 00 00 000000

↓

$ sudo grep "Name:\|J:\|BB:" /sys/kernel/debug/tegra_gpio                                                                                                                                                                
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
 J: 2:1 00 00 00 00 00 00 000000
BB: 6:3 00 00 00 00 00 00 000000
```

上記に変更をしなくてはならない。
デバイスツリーの再構成が必要になるらしいが、[当リンク](https://denor.jp/nvidia-jetson-nano%E9%96%8B%E7%99%BA%E8%80%85%E3%82%AD%E3%83%83%E3%83%88%E3%81%AE%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E8%A8%AD%E5%AE%9A)を参考にUSBシリアルデバイスを接続して、u-bootの途中でレジスタを変更することで次回再起動まで有効にすることができる。

3秒間のブート待ちの間にエンターを押し、u-bootのプロンプトに入る。

```
Tegra210 (P3450-Porg) # mw 0x70003144 0x6044
Tegra210 (P3450-Porg) # mw 0x70003148 0x6044
Tegra210 (P3450-Porg) # mw 0x7000314c 0x6044
Tegra210 (P3450-Porg) # mw 0x70003150 0x6044

Tegra210 (P3450-Porg) # mw 0x6000d204 0
Tegra210 (P3450-Porg) # mw 0x6000d60c 0

Tegra210 (P3450-Porg) # boot
```

上記でOS起動後に下記設定を確認できる。

```
$ sudo grep "Name:\|J:\|BB:" /sys/kernel/debug/tegra_gpio                                                                                                                                                                
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
 J: 2:1 00 00 00 00 00 00 000000
BB: 6:3 00 00 00 00 00 00 000000
```

これで40pinヘッダーへI2Sを接続設定が完了した

現在JetPack 4.3 (r32.3.1)には、[Jetson-IO tool](https://qiita.com/kitazaki/items/a445994f1f46a1b15f78)という上記および再起動後も設定が反映されるようにデバイスツリーの再構築を行ってくれるツールが存在するので楽になった。

##トラブル発生
何度か再起動をすると音が全くでなくなり、ぷつぷつという音だけがわずかに出る状態になってしまった。
このトラブルの調査はnVIDIA developer Forumに投稿し、RMAで一度Jetson Nanoを交換したが再発。一度起こるとコーデックボードを外しても発振したまま。
結局のところ、I2Sの4つのpinに入っている双方向レベルシフターTXB0108が発振していることが分かった。
それは容量負荷にデリケートなようで、プローブを当てたりして壊してしまったのかもしれない。
https://devtalk.nvidia.com/default/topic/1063127/jetson-nano/jetson-nano-i2s-strange-output-/post/5396024/#5396024

データシートから引用：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/6b5394e8-6599-33a5-a71d-8d94291a3014.png)
上記回路図からB側は発振していたが、1.8V側のA1,A2,A3pinなどを直接オシロで当たると、きちんとした波形が観測できた。


現在、nVIDIAからは以下のような注意喚起のドキュメントが出ている。

Jetson Nano Developer Kit 40-Pin Expansion Header GPIO Usage Considerations Applications Note　1.0
2020/02/18
This application note describes how to work with the signals on the 40-pin expansion header on the NVIDIA® Jetson Nano™ Developer Kit carrier board that pass through TI TXB0108RGYR level shifters.


今後気を付けるとして、I2Sが使えないJetson Nanoを救うためにJetson Nano上のTXB0108をヒートガンで外して、A-Bをワイヤーで直結させてみた。

そうすると、40pinには1.8VロジックレベルのI2S信号が来るわけだが、レベルシフターは依然として必要になる。双方向型は自動検知で信号の向きを決定しているようだが、調べているとトラブルが多いようだ。よって自動検知でなく手動で方向を設定できるチップを探していると見つかった。
http://www.tij.co.jp/product/jp/SN74AVC4T774
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/67872f18-8331-97c9-7a5c-f4d1f5526d5f.png)

4本の信号線を設定で方向を決められるレベルシフターのようだ。ちょうどいい。

以下のような回路図を引いて、Jetson Nano とコーデックボードに割り込ませることにした。1.8Vはレギュレータを載せて3.3Vから生成させる形。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/c50bb483-8f68-79e9-9fe2-c968fbee722d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/6e70eca1-a1da-ea8f-3a3a-675c90b38967.png)
基盤を作成してみた。

これを割り込ませることでTXB0108を無効化したJetson Nanoで、オーディオコーデックが使えるようになった。
前回のRaspberry piで使用したAudacityでの設定例。
録音、再生ともにtegra-snd-t210ref-mobile-rt565x: -(hw:1,0)で認識できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/e689d914-b4eb-57a0-3df8-c586327f05a6.png)