Jetson Nano で Framebuffer Driver を使用する (JetPack 4.6対応)

# はじめに

過去JetPack 4.3(r32.3.1)でFramebuffer Driverを使用する記事を書きました。

https://qiita.com/kitazaki/items/9f6119d7dc21cd29268e

同じディスプレイ(型仕様は1.3' 240*240 IPS ST7789(CS ピン無し)だが<a href="https://amzn.to/3sc4hoi">入手先</a>が異なる)で同じ手順でうまく動作しないというコメントをいただきましたので、同じ<a href="https://amzn.to/3sc4hoi">入手先</a>のディスプレイを使用して最新JetPack 4.6で動作検証することにしました。

### 環境

- Jetson Nano 4GB (A02)
- Jetson Nano 4GB (B01)
- Jetson Nano 2GB
- 1.3' IPS SPI 240x240 ST7789ディスプレイ
- 1.8' TFT SPI 128x160 ST7735ディスプレイ
- 2.4’ TFT SPI 240x320 ili9341ディスプレイ

(2022/2/26追記: Jetson Nano 2GBでも動作しました。)
(2022/3/4追記: Framebuffer Driverでも動作しました。)
(2022/3/5追記: Jetson Nano 4GB (B01)でも動作しました。)

# SPIを有効にする

Jetson-IO tool を使用してSPI (spi1)を有効にします。
JetPack 4.3(r32.3.1)で追加された時は最初の実行でエラーになる問題があり、ワークアラウンドで回避しました。

https://qiita.com/kitazaki/items/34505828019c102b8701

JetPack 4.4 DP(r32.4.2)では問題が解消されましたが、JetPack 4.6では問題が再発しました。

(2022/2/26追記: Jetson Nano 2GBでは問題ありませんでした。)
(2022/3/5追記: Jetson Nano 4GB (B01)では問題ありませんでした。)

jetson-io.py を実行すると、一瞬、画面に何かが表示されて直ぐに終了してしまいます。
lessコマンドでエラー内容を確認すると、JetPack 4.3の時と同じエラー(DTBが見つからない)が出力されていました。

```bash
$ sudo /opt/nvidia/jetson-io/jetson-io.py | less

FATAL ERROR!
No DTB found for NVIDIA Jetson Nano Developer Kit!
Press any key to terminate
```

JetPack 4.3の時と同じワークアラウンドを実行して、再度、jetson-io.py を実行します。

```bash
$ cd /boot
$ sudo cp *.dtb* dtb/
$ sudo /opt/nvidia/jetson-io/jetson-io.py
```

## Jetson-IO

Configure Jetson 40pin Headerを選択します。(Enterキーを押す)

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/0d7db6b0-05a4-dc82-8a78-8b9ace1b5f36.jpeg)

Configure header pins manuallyを選択します。(矢印キーでカーソルを選択してEnterキーを押す)

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/e066ab33-ca48-76cf-a912-78e71bfeff57.jpeg)

spi1を選択します。(矢印キーでカーソルを移動してスペースキーを押すと[*]マークが付きます)
spi1を選択した後はBackで戻ります。(矢印キーでカーソルを移動してEnterキーを押す)

![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/f4673a3d-cca9-a8e4-b6e3-33bfdfff7c34.jpeg)

Save pin changesを選択します。(矢印キーでカーソルを選択してEnterキーを押す)

![4-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/a3748762-1895-45d8-fc89-689e96c4fce9.jpeg)

Save and reboot to reconfigure pinsを選択します。(矢印キーでカーソルを選択してEnterキーを押す)

![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/576cbbcd-c301-96fb-1724-c3bdafe56823.jpeg)

DTBファイルが格納され、何かキーを押すとJetson Nanoが再起動します。

![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/77cf44ac-c9e1-39f4-0c1c-72d26b7f34ef.jpeg)

再起動後にSPIが有効になっているか確認します。

## SPIデバイスを認識させる

SPIデバイスを認識させるためには、OS起動後にmodprobeコマンドを実行する必要があります。

```bash
$ sudo modprobe spidev
```

SPIデバイスが認識されているかどうか確認します。

```bash
$ ls /dev/spi*
/dev/spidev0.0 /dev/spidev0.1 /dev/spidev1.0 /dev/spidev1.1
```

OS起動時にSPIデバイスを認識させる(カーネルモジュールを読み込ませる)ためには、
/etc/modules-load.d/modules.confファイルにspidevを記載する必要があります。

```text:/etc/modules-load.d/modules.conf
spidev
```

# SPIデバイスの動作確認

## ループバックのテスト

https://sciencompass.com/electrical_work/jetson-nano/spi-set

### 配線

ピン番号19(MOSI)とピン番号21(MISO)をジャンパー線で接続します。

### 実行

pythonのSPI通信モジュール(py-spidev)をインストールします。

```bash
$ sudo apt install python3-setuptools python3-pip python3-pil python3-numpy python3-willow python-willow
$ git clone git://github.com/doceme/py-spidev
$ cd py-spidev
$ sudo python3 setup.py install
```

(2022年3月5日追記: aptコマンでエラーが出力される場合の対応)
python3-willow、python-willowを除外してインストールします。

```bash
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package python3-willow
E: Unable to locate package python-willow
```

テストスクリプト(loop.py)を作成して実行します。
1秒毎に"0x01 0x02"が出力されれば正常です。

```bash
$ python3 loop.py
0x01 0x02
0x01 0x02
...
```

```python:loop.py
#!/usr/bin/env python
 
# loopback test script
# connect MOSI and MISO
 
import spidev
import time
 
spi = spidev.SpiDev()
spi.open(0, 0)
 
def BytesToHex(Bytes):
  return ''.join(["0x%02X " % x for x in Bytes]).strip()
 
try:
  while True:
    resp = spi.xfer2([0x01, 0x02])
    print(BytesToHex(resp))
    time.sleep(1)
 
except KeyboardInterrupt:
  spi.close()
```

## ディスプレイ(CSピンが無い1.3' IPS 240*240 @ ST7789)の表示確認

Jetson Nanoとディスプレイとの配線については以前の記事と同じです。

1.3' 240*240 IPS ST7789

| 1.3' 240*240 IPS ST7789 | Jetson Nano ピン番号 (ラズパイGPIO、Linux sysfs GPIO) |
| --- | --- |
| GND | 6 (GND) |
| VCC | 1 (3.3V) |
| SCL (SPI clock line) | 23 (SCK) |
| SDA (SPI data line) | 19 (MOSI) |
| RES | 18 (GPIO 24、gpio15)
| DC | 22 (GPIO 25、gpio13)
| BLK (Backlight LED Kathode) | 13 (GPIO 27、gpio14) |

https://qiita.com/kitazaki/items/676fdba01b0f145ba976

### ST7789 (Python_ST7789) ライブラリ

https://jiwashin.blogspot.com/2020/04/how-to-connect-ST7789-LCD-without-CS-pin.html

```bash
$ sudo apt install python3-setuptools python3-pip python3-pil python3-numpy python3-willow python-willow
$ git clone https://github.com/solinnovay/Python_ST7789
$ cd Python_ST7789
```

* 後述のPimoroni ライブラリをインストールすると、ST7789 (Python_ST7789)　ライブラリが上書きされて動かなくなるので、ライブラリ名を修正する。

```bash
$ mv ST7789 ST7789_1
```

ST7789 (Python_ST7789)　ライブラリをインストールする。

```bash
$ sudo python3 setup.py install
```

サンプルプログラム(clock_EN.py、または、clock_JP.py)を修正して実行します。
SPI_DEVICE = 0 → 1に変更する (/dev/spidev0.0ではなく、/dev/spidev0.1を使用する) ことがポイントです。

```bash
$ cd examples
$ vi clock_EN.py
または
$ vi clock_JP.py
```

```python:clock_EN.py、または、clock_JP.py
import ST7789 as TFT
↓
import ST7789_1 as TFT

RST = 27
↓
RST = 24

LED = 24
↓
LED = 27

SPI_DEVICE = 0
↓
SPI_DEVICE = 1
```

clock_EN.pyはそのまま実行可能です。
clock_JP.pyは日本語フォントのインストールが必要です。

```bash
$ python3 clock_EN.py
または
$ wget https://github.com/indico/indico-fonts/raw/master/indico_fonts/kochi-gothic-subst.ttf
$ sudo mkdir /usr/share/fonts/truetype/kochi
$ sudo mv kochi-gothic-subst.ttf /usr/share/fonts/truetype/kochi
$ python3 clock_JP.py
```

### Pimoroni ライブラリ

https://www.mikan-tech.net/entry/raspi-st7789-lcd

テストスクリプト(display.py)を作成して実行します。
ST7789()はport=0, cs=1, rst=24, dc=25, backlight=27を指定します。
cs=0 → 1 に変更する(/dev/spidev0.0ではなく、/dev/spidev0.1を使用する)ことがポイントです。

```bash
$ pip3 install st7789
$ python3 display.py
```

```python:display.py
import ST7789
from PIL import Image

# Create a display instance
disp = ST7789.ST7789(port=0, cs=1, rst=24, dc=25, backlight=27, spi_speed_hz=80 * 1000 * 1000)

# Added: Change to SPI MODE 3
disp._spi.mode = 3
disp.reset()
disp._init()

# Open image file
image = Image.open("/usr/share/backgrounds/NVIDIA_Login_Logo.png")

# Resize to screen size
image = image.resize((disp.width, disp.height), resample=Image.LANCZOS)

# Show it on display
disp.display(image)
```

# Framebufferの動作確認

## カーネルビルド

editConfig.shコマンドを使用してカーネルコンフィグを編集します。

```bash
$ ./editConfig.sh
```

https://qiita.com/kitazaki/items/95d09498244171cfe5d9

Framebuffer Driver (fbtft_driver) を有効化します。

場所は
Linux Kernel Configuration
　└─> Device Drivers
　　└─> Staging drivers 
　　　└─> Support for small TFT LCD display modules 

上下の矢印キーでカーソルを移動して、Enterキーを押すと配下へ移動します。
Support for small TFT LCD display modulesまで移動してスペースキーを押すと[M]の表示に変わります。

```bash
[ ] Support for small TFT LCD display modules 
↓
[M] Support for small TFT LCD display modules 
```

Enterキーを押して配下へ移動します。
表示される全ての項目でスペースキーを押して[M]の表示に変更します。

カーネルイメージとカーネルモジュールをビルドします。

```bash
$ ./makeKernel.sh
$ ./makeModules.sh
```

ビルドが完了したら新しい Image をコピーして再起動します。

```bash
$ ./copyImage.sh
$ sudo reboot
```

OSが起動したらカーネルモジュールを組み込みます。

組み込み前

```bash
$ lsmod
Module                  Size  Used by
bnep                   18758  2
xt_conntrack            3979  1
ipt_MASQUERADE          2570  1
nf_nat_masquerade_ipv4     3993  1 ipt_MASQUERADE
nf_conntrack_netlink    32712  0
nfnetlink               9652  2 nf_conntrack_netlink
xt_addrtype             3915  2
iptable_filter          3008  1
iptable_nat             3423  1
nf_conntrack_ipv4      14094  2
nf_defrag_ipv4          2129  1 nf_conntrack_ipv4
nf_nat_ipv4             8112  1 iptable_nat
nf_nat                 24700  2 nf_nat_masquerade_ipv4,nf_nat_ipv4
nf_conntrack          131065  6 nf_conntrack_ipv4,nf_conntrack_netlink,nf_nat_masquerade_ipv4,xt_conntrack,nf_nat_ipv4,nf_nat
br_netfilter           17460  0
zram                   29049  4
overlay                51689  0
nvgpu                1727544  18
userspace_alert         6769  0
spidev                 14443  0
ip_tables              21421  2 iptable_filter,iptable_nat
x_tables               38016  5 ip_tables,iptable_filter,ipt_MASQUERADE,xt_addrtype,xt_conntrack

$ ls /dev/fb*
/dev/fb0
/dev/fb1
```

組み込み
cs=1 を指定する (/dev/spidev0.0ではなく、/dev/spidev0.1を使用する) ことがポイントです。(指定しないとデフォルトでcs=0)

```bash
$ sudo modprobe fbtft_device name=flexfb busnum=0 cs=1 gpios=reset:15,dc:13,led:14 speed=40000000 bgr=1 fps=60 custom=1 height=240 width=240 mode=3

$ sudo modprobe flexfb setaddrwin=0 width=240 height=240 init=-1,0x11,-2,120,-1,0x36,0x70,-1,0x3A,0x05,-1,0xB2,0x0C,0x0C,0x00,0x33,0x33,-1,0xB7,0x35,-1,0xBB,0x1A,-1,0xC0,0x2C,-1,0xC2,0x01,-1,0xC3,0x0B,-1,0xC4,0x20,-1,0xC6,0x0F,-1,0xD0,0xA4,0xA1,-1,0x21,-1,0xE0,0x00,0x19,0x1E,0x0A,0x09,0x15,0x3D,0x44,0x51,0x12,0x03,0x00,0x3F,0x3F,-1,0xE1,0x00,0x18,0x1E,0x0A,0x09,0x25,0x3F,0x43,0x52,0x33,0x03,0x00,0x3F,0x3F,-1,0x29,-3
```

組み込み後
/dev/fb2が認識されます。

(2022/2/26追記: Jetson Nano 2GBでは/dev/fb1が認識されました。)

```bash
$ lsmod
Module                  Size  Used by
flexfb                 17049  0
fbtft_device           51795  0
fbtft                  45808  2 fbtft_device,flexfb
bnep                   18758  2
xt_conntrack            3979  1
ipt_MASQUERADE          2570  1
nf_nat_masquerade_ipv4     3993  1 ipt_MASQUERADE
nf_conntrack_netlink    32712  0
nfnetlink               9652  2 nf_conntrack_netlink
xt_addrtype             3915  2
iptable_filter          3008  1
iptable_nat             3423  1
nf_conntrack_ipv4      14094  2
nf_defrag_ipv4          2129  1 nf_conntrack_ipv4
nf_nat_ipv4             8112  1 iptable_nat
nf_nat                 24700  2 nf_nat_masquerade_ipv4,nf_nat_ipv4
nf_conntrack          131065  6 nf_conntrack_ipv4,nf_conntrack_netlink,nf_nat_masquerade_ipv4,xt_conntrack,nf_nat_ipv4,nf_nat
br_netfilter           17460  0
zram                   29049  4
overlay                51689  0
nvgpu                1727544  18
userspace_alert         6769  0
spidev                 14443  0
ip_tables              21421  2 iptable_filter,iptable_nat
x_tables               38016  5 ip_tables,iptable_filter,ipt_MASQUERADE,xt_addrtype,xt_conntrack

$ ls /dev/fb*
/dev/fb0
/dev/fb1
/dev/fb2

$ dmesg
[  101.658018] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[  101.675206] fbtft_device: module is from the staging directory, the quality is unknown, you have been warned.
[  101.685860] spidev spi0.0: tegra-spidev spi0.0 33000kHz 8 bits mode=0x00
[  101.685866] spidev spi0.1: tegra-spidev spi0.1 33000kHz 8 bits mode=0x00
[  101.685870] spidev spi1.0: tegra-spidev spi1.0 33000kHz 8 bits mode=0x00
[  101.685874] spidev spi1.1: tegra-spidev spi1.1 33000kHz 8 bits mode=0x00
[  101.685878] qspi_mtd spi32766.0: MX25U3235F spi32766.0 104000kHz 8 bits mode=0x00
[  101.685993] spidev spi0.1: Deleting spi0.1
[  101.686587] fbtft_device: GPIOS used by 'flexfb':
[  101.686591] fbtft_device: 'reset' = GPIO15
[  101.686593] fbtft_device: 'dc' = GPIO13
[  101.686594] fbtft_device: 'led' = GPIO14
[  101.686600] spidev spi0.0: tegra-spidev spi0.0 33000kHz 8 bits mode=0x00
[  101.686604] spidev spi1.0: tegra-spidev spi1.0 33000kHz 8 bits mode=0x00
[  101.686608] spidev spi1.1: tegra-spidev spi1.1 33000kHz 8 bits mode=0x00
[  101.686611] qspi_mtd spi32766.0: MX25U3235F spi32766.0 104000kHz 8 bits mode=0x00
[  101.686614] spi spi0.1: flexfb spi0.1 40000kHz 8 bits mode=0x03
[  110.420985] flexfb: module is from the staging directory, the quality is unknown, you have been warned.
[  110.736630] graphics fb2: flexfb frame buffer, 240x240, 112 KiB video memory, 4 KiB DMA buffer memory, fps=62, spi0.1 at 40 MHz
```

## 1.8' SPI 128x160 ST7735 ディスプレイ

Jetson Nanoとディスプレイとの配線については以前の記事と同じです。

1.8' SPI 128x160 ST7735

| 1.8' SPI 128x160 ST7735 | Nano ピン番号 |
| --- | --- |
| 1-RES | 18 (GPIO 24) |
| 2-CS | 24 (CS0) |
| 3-D/C | 22 (GPIO 25) |
| 4-DIN | 19 (MOSI) |
| 5-CLK | 23 (SCK) |
| 6-VCC | 2 (5V) |
| 7-BL | 2 (5V) |
| 8-GND | 6 (GND) |

https://qiita.com/kitazaki/items/676fdba01b0f145ba976

カーネルモジュールを組み込みます。

```bash
$ sudo modprobe fbtft_device name=adafruit18 rotate=90 busnum=0 cs=0 gpios=reset:15,dc:13 speed=40000000
```

SPIのCS0をCS1へ変更する場合は、ジャンパー線の配線を以下のとおり変更します。

| 1.8' SPI 128x160 ST7735 | Nano ピン番号 |
| --- | --- |
| 2-CS | 26 (CS1) |

カーネルモジュールの組み込みもcs=0→1へ変更します。

```bash
$ sudo modprobe fbtft_device name=adafruit18 rotate=90 busnum=0 cs=1 gpios=reset:15,dc:13 speed=40000000
```

組み込み後
/dev/fb2が認識されます。

```bash
$ dmesg
…
[   63.971640] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[   63.990874] fbtft_device: module is from the staging directory, the quality is unknown, you have been warned.
[   64.001498] spidev spi0.0: tegra-spidev spi0.0 33000kHz 8 bits mode=0x00
[   64.001506] spidev spi0.1: tegra-spidev spi0.1 33000kHz 8 bits mode=0x00
[   64.001512] spidev spi1.0: tegra-spidev spi1.0 33000kHz 8 bits mode=0x00
[   64.001518] spidev spi1.1: tegra-spidev spi1.1 33000kHz 8 bits mode=0x00
[   64.001524] qspi_mtd spi32766.0: MX25U3235F spi32766.0 104000kHz 8 bits mode=0x00
[   64.001676] spidev spi0.0: Deleting spi0.0
[   64.002128] fbtft_device: GPIOS used by 'adafruit18':
[   64.002132] fbtft_device: 'reset' = GPIO15
[   64.002134] fbtft_device: 'dc' = GPIO13
[   64.002140] spidev spi0.1: tegra-spidev spi0.1 33000kHz 8 bits mode=0x00
[   64.002144] spidev spi1.0: tegra-spidev spi1.0 33000kHz 8 bits mode=0x00
[   64.002147] spidev spi1.1: tegra-spidev spi1.1 33000kHz 8 bits mode=0x00
[   64.002151] qspi_mtd spi32766.0: MX25U3235F spi32766.0 104000kHz 8 bits mode=0x00
[   64.002154] spi spi0.0: fb_st7735r spi0.0 40000kHz 8 bits mode=0x00
[   64.011627] fb_st7735r: module is from the staging directory, the quality is unknown, you have been warned.
[   64.926598] graphics fb2: fb_st7735r frame buffer, 160x128, 40 KiB video memory, 4 KiB DMA buffer memory, fps=20, spi0.0 at 40 MHz

$ ls -la /dev/fb*
crw-rw---- 1 root video 29, 0  2月 25 01:28 /dev/fb0
crw-rw---- 1 root video 29, 1  2月 25 01:28 /dev/fb1
crw-rw---- 1 root video 29, 2  3月  4 15:08 /dev/fb2
```

## - 2.4’ TFT SPI 240x320 ili9341 ディスプレイ

Jetson Nanoとディスプレイとの配線は以下のとおりです。

| 2.4’ TFT SPI 240x320 ili9341 | Nano ピン番号 |
| --- | --- |
| 1-VCC | 1 (3.3V) |
| 2-GND | 6 (GND) |
| 3-CS | 24 (CS0) |
| 4-RESET | 18 (GPIO 24) |
| 5-DC | 22 (GPIO 25) |
| 6-SDI(MOSI) | 19 (MOSI) |
| 7-SCK | 23 (SCK) |
| 8-LED | 1 (3.3V) |

![ili9341_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/fffc50df-53de-456c-671e-5d0b7df75255.jpeg)
![ili9341_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/4e142211-9093-4547-fa76-1e2def41d125.jpeg)

カーネルモジュールを組み込みます。

```bash
sudo modprobe fbtft_device name=adafruit28 rotate=90 busnum=0 cs=0 gpios=reset:15,dc:13 speed=40000000 
```

組み込み後
/dev/fb2が認識されます。

```bash
$ dmesg
…
[   66.252423] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[   66.269254] fbtft_device: module is from the staging directory, the quality is unknown, you have been warned.
[   66.279844] spidev spi0.0: tegra-spidev spi0.0 33000kHz 8 bits mode=0x00
[   66.279850] spidev spi0.1: tegra-spidev spi0.1 33000kHz 8 bits mode=0x00
[   66.279854] spidev spi1.0: tegra-spidev spi1.0 33000kHz 8 bits mode=0x00
[   66.279858] spidev spi1.1: tegra-spidev spi1.1 33000kHz 8 bits mode=0x00
[   66.279863] qspi_mtd spi32766.0: MX25U3235F spi32766.0 104000kHz 8 bits mode=0x00
[   66.279976] spidev spi0.0: Deleting spi0.0
[   66.280367] fbtft_device: GPIOS used by 'adafruit28':
[   66.280370] fbtft_device: 'reset' = GPIO15
[   66.280372] fbtft_device: 'dc' = GPIO13
[   66.280378] spidev spi0.1: tegra-spidev spi0.1 33000kHz 8 bits mode=0x00
[   66.280381] spidev spi1.0: tegra-spidev spi1.0 33000kHz 8 bits mode=0x00
[   66.280385] spidev spi1.1: tegra-spidev spi1.1 33000kHz 8 bits mode=0x00
[   66.280389] qspi_mtd spi32766.0: MX25U3235F spi32766.0 104000kHz 8 bits mode=0x00
[   66.280392] spi spi0.0: fb_ili9341 spi0.0 40000kHz 8 bits mode=0x00
[   66.290325] fb_ili9341: module is from the staging directory, the quality is unknown, you have been warned.
[   66.604536] graphics fb2: fb_ili9341 frame buffer, 320x240, 150 KiB video memory, 16 KiB DMA buffer memory, fps=20, spi0.0 at 40 MHz

$ ls -la /dev/fb*
crw-rw---- 1 root video 29, 0 12月 10 18:15 /dev/fb0
crw-rw---- 1 root video 29, 1 12月 10 18:15 /dev/fb1
crw-rw---- 1 root video 29, 2  3月  4 17:26 /dev/fb2
```

# Framebuffer Driver のテスト

```bash
$ sudo apt install libnetpbm10-dev
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/geert/fbtest.git
$ cd fbtest
$ make
$ ./fbtest --fbdev /dev/fb2
Using drawops cfb16 (16 bpp packed pixels)
Available visuals:
  Monochrome
  Grayscale 32
  Truecolor 5:6:5:0
Using visops truecolor
Running all tests
test001: PASSED
test002: PASSED
test003: PASSED
test004: PASSED
test005: PASSED
test006: PASSED
test008: PASSED
test009: PASSED
test010: PASSED
Benchmarking... 10x10 squares: 34.98 Mpixels/s
Benchmarking... 20x20 squares: 159.27 Mpixels/s
Benchmarking... 50x50 squares: 270.49 Mpixels/s
Benchmarking... 100x100 squares: 401.93 Mpixels/s
Benchmarking... 200x200 squares: 600.54 Mpixels/s
test012: PASSED
Benchmarking... R5 circles: 14.51 Mpixels/s
Benchmarking... R10 circles: 54.84 Mpixels/s
Benchmarking... R25 circles: 179.63 Mpixels/s
Benchmarking... R50 circles: 253.05 Mpixels/s
Benchmarking... R100 circles: 270.27 Mpixels/s
test013: PASSED
```

(2022/2/26追記: Jetson Nano 2GBでは/dev/fb1を指定します。)

```bash
$ ./fbtest --fbdev /dev/fb1
```

# まとめ

JetPack4.6でもFramebuffer Driverが動きました！

![IMG_9959.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/0dfe76f8-f7ec-bc0c-cac1-88a348da138a.jpeg)

https://youtu.be/PdNPxK8A4NY

* 2022/2/26追記: Jetson Nano 2GB

![IMG_9964.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/a3f92649-5b69-3d74-fd98-e4d0c74d9f55.jpeg)

![IMG_9965.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/4d7688e0-c485-8a42-6db9-ba0aa98f9c94.jpeg)

https://youtu.be/cDErhdmhAFw

* 2022/3/4追記: 1.8' SPI 128x160 ST7735

https://youtu.be/iHbFqjZTMuk

* 2022/3/4追記: 2.4’ TFT SPI 240x320 ili9341 

https://youtu.be/ZkJN-rBE8Fo

* 2022/3/5追記: Jetson Nano 4GB (B01)

![IMG_0023.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/b1abfec4-5888-6272-eb27-9316bdd5e041.jpeg)

![IMG_0024.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/6c73e973-6804-ea54-d1e3-23cb27f9f1f1.jpeg)

https://youtu.be/7GNwCqh_ktc

* 2022/3/10追記: SPI2でもFramebuffer Driverが動きました

# SPI2でFramebuffer Driverを動かす

## Jetson-IO

![SPI2_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/ef71be6c-e043-5736-fedb-81db91fd17b9.png)
![SPI2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/e291f368-fab9-33bc-c78d-4a800b3f5f1c.png)

## ループバックのテスト

### 配線

ピン番号37(MOSI)とピン番号22(MISO)をジャンパー線で接続します。

![looptest.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/f9e18ab8-0b90-d964-b918-f28a6fe7d26d.jpeg)

### テストスクリプト

spi.open(1, 0)を指定します。

```python:loop2.py
#!/usr/bin/env python
 
# loopback test script
# connect MOSI and MISO
 
import spidev
import time
 
spi = spidev.SpiDev()
spi.open(1, 0)
 
def BytesToHex(Bytes):
  return ''.join(["0x%02X " % x for x in Bytes]).strip()
 
try:
  while True:
    resp = spi.xfer2([0x01, 0x02])
    print(BytesToHex(resp))
    time.sleep(1)
 
except KeyboardInterrupt:
  spi.close()
```

## ディスプレイ(CSピンが無い1.3' IPS 240*240 @ ST7789)の表示確認

### 配線

Jetson Nanoとディスプレイとの配線については以下のとおりです。

1.3' 240*240 IPS ST7789

| 1.3' 240*240 IPS ST7789 | Jetson Nano ピン番号 (ラズパイGPIO、Linux sysfs GPIO) |
| --- | --- |
| GND | 6 (GND) |
| VCC | 1 (3.3V) |
| SCL (SPI clock line) | 13 (SCK) |
| SDA (SPI data line) | 37 (MOSI) |
| RES | 24 (GPIO 8、gpio19)
| DC | 26 (GPIO 7、gpio20)
| BLK (Backlight LED Kathode) | 19 (GPIO 10、gpio16) |

### ST7789 (Python_ST7789) ライブラリ

```python:clock_EN.pyの変更点
import ST7789 as TFT
↓
import ST7789_1 as TFT

RST = 27
↓
RST = 8

DC  = 25
↓
DC  = 7

LED = 24
↓
LED = 10

SPI_PORT = 0
↓
SPI_PORT = 1

SPI_DEVICE = 0
↓
SPI_DEVICE = 1
```

![IMG_0038.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/63ba7712-0791-d1a8-4a8a-b210b0e9846c.jpeg)
![clock_EN2_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/e7c1ead1-42e8-b525-7a4f-edb5dbb5af31.jpeg)
![clock_EN2_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/78740db0-6327-57ea-9d94-0bc5c2e08908.jpeg)

### Pimoroni ライブラリ

```python:display2.py
import ST7789
from PIL import Image

# Create a display instance
disp = ST7789.ST7789(port=1, cs=1, rst=8, dc=7, backlight=10, spi_speed_hz=80 * 1000 * 1000)

# Added: Change to SPI MODE 3
disp._spi.mode = 3
disp.reset()
disp._init()

# Open image file
image = Image.open("/usr/share/backgrounds/NVIDIA_Login_Logo.png")

# Resize to screen size
image = image.resize((disp.width, disp.height), resample=Image.LANCZOS)

# Show it on display
disp.display(image)
```

![display2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/9b2cf6b2-f98a-9fb9-f195-47654b094852.jpeg)

## Framebufferの動作確認

### 組み込み
 
```bash
$ sudo modprobe fbtft_device name=flexfb busnum=1 cs=1 gpios=reset:19,dc:20,led:16 speed=40000000 bgr=1 fps=60 custom=1 height=240 width=240 mode=3

$ sudo modprobe flexfb setaddrwin=0 width=240 height=240 init=-1,0x11,-2,120,-1,0x36,0x70,-1,0x3A,0x05,-1,0xB2,0x0C,0x0C,0x00,0x33,0x33,-1,0xB7,0x35,-1,0xBB,0x1A,-1,0xC0,0x2C,-1,0xC2,0x01,-1,0xC3,0x0B,-1,0xC4,0x20,-1,0xC6,0x0F,-1,0xD0,0xA4,0xA1,-1,0x21,-1,0xE0,0x00,0x19,0x1E,0x0A,0x09,0x15,0x3D,0x44,0x51,0x12,0x03,0x00,0x3F,0x3F,-1,0xE1,0x00,0x18,0x1E,0x0A,0x09,0x25,0x3F,0x43,0x52,0x33,0x03,0x00,0x3F,0x3F,-1,0x29,-3
```

### 組み込み後の確認

```bash
$ dmesg
...
[   31.685114] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[   32.894670] fbtft_device: module is from the staging directory, the quality is unknown, you have been warned.
[   32.908146] spidev spi0.0: tegra-spidev spi0.0 33000kHz 8 bits mode=0x00
[   32.908181] spidev spi0.1: tegra-spidev spi0.1 33000kHz 8 bits mode=0x00
[   32.908209] spidev spi1.0: tegra-spidev spi1.0 33000kHz 8 bits mode=0x00
[   32.908237] spidev spi1.1: tegra-spidev spi1.1 33000kHz 8 bits mode=0x00
[   32.908266] qspi_mtd spi32766.0: MX25U3235F spi32766.0 104000kHz 8 bits mode=0x00
[   32.908890] spidev spi1.1: Deleting spi1.1
[   32.910425] fbtft_device: GPIOS used by 'flexfb':
[   32.910429] fbtft_device: 'reset' = GPIO19
[   32.910430] fbtft_device: 'dc' = GPIO20
[   32.910432] fbtft_device: 'led' = GPIO16
[   32.910437] spidev spi0.0: tegra-spidev spi0.0 33000kHz 8 bits mode=0x00
[   32.910441] spidev spi0.1: tegra-spidev spi0.1 33000kHz 8 bits mode=0x00
[   32.910444] spidev spi1.0: tegra-spidev spi1.0 33000kHz 8 bits mode=0x00
[   32.910447] qspi_mtd spi32766.0: MX25U3235F spi32766.0 104000kHz 8 bits mode=0x00
[   32.910450] spi spi1.1: flexfb spi1.1 40000kHz 8 bits mode=0x03
[   33.908122] vdd-fan: disabling
[   33.908164] vdd-usb-vbus: disabling
[   33.908195] vdd-usb-vbus2: disabling
[   33.908292] vddio-sdmmc3-ap: disabling
[   33.908920] avdd-io-edp-1v05: disabling
[   33.908952] vdd-usb-hub-en: disabling
[   50.892936] flexfb: module is from the staging directory, the quality is unknown, you have been warned.
[   51.195960] graphics fb2: flexfb frame buffer, 240x240, 112 KiB video memory, 4 KiB DMA buffer memory, fps=62, spi1.1 at 40 MHz
```

https://youtu.be/NRytzPrJItE

* 2022/3/19 追記

# JetPack 4.6.1でも動作を確認

https://qiita.com/kitazaki/items/915663f84257504f4f73