Wren6991/PicoDVI - RP2040を使用したHDMI映像出力

# 概要
RaspberryPi Picoが発売されてかなりの時間が経過しました。
ソフトウェアもかなり成熟してきた印象があるので、今回はHDMIコネクタを使用した映像出力を試してみたいと思います。

# 注意
- `bad_apple`や`mandel-full`、`vista`は映像が乱れているため、正常な映像を確認できませんでした。
- `vista-palette`は再生できませんでした。

上記に関して、何らかの事前設定が必要な可能性があるため、ご存じの方はコメントいただけますと幸いです。

# 環境
- M1 macbook
  - macOS Ventura 13.7.1
- Parallels Desktop 19 for mac
  - バージョン 19.4.1 (54985)
  - `Debian GNU Linux 12 ARM64`を使用


- 使用したボード (RP2040を使用)
  - Waveshare RP2040-PiZero [販売ページ](https://www.waveshare.com/rp2040-pizero.htm)
  - Pimoroni Pico DV Demo Base [販売ページ](https://shop.pimoroni.com/products/pimoroni-pico-dv-demo-base)
  - Raspberry Pi Pico (RP2040)

# リポジトリ
- https://github.com/Wren6991/PicoDVI
  - Commits on Aug 15, 2024 [Add pin definitions for Waveshare RP2040-PiZero]
  - CommitID: 62c07fb6401187a25cff8edc71650705887a7cb4

- https://github.com/raspberrypi/pico-sdk
  - Commits on Aug 8, 2024 [SDK 2.0.0 release]
  - CommitID: efe2103f9b28458a1615ff096054479743ade236

# ビルド手順

リポジトリのクローン
(リポジトリ更新で環境が変化する可能性もあるため、現時点で動作確認の取れた最新バージョンで固定)
```
mkdir work_dir && cd work_dir
git clone https://github.com/Wren6991/PicoDVI.git
cd PicoDVI
git checkout 62c07fb6401187a25cff8edc71650705887a7cb4

cd .. 
cd pico-sdk
git clone https://github.com/raspberrypi/pico-sdk.git
git checkout efe2103f9b28458a1615ff096054479743ade236
```

## pico-sdk
[#unix-command-line](https://github.com/raspberrypi/pico-sdk#unix-command-line)を参考に事前準備↓
```
sudo apt install cmake && \
         gcc-arm-none-eabi && \
         libnewlib-arm-none-eabi && \
         libstdc++-arm-none-eabi-newlib
```

## PicoDVI
[Building](https://github.com/Wren6991/PicoDVI/tree/master/software#building)ページを参考にビルド作業を実施

```
cd work_dir/PicoDVI/software
mkdir build
cd build

cmake \
-DPICO_SDK_PATH=../../../pico-sdk \
-DPICO_COPY_TO_RAM=1 \
-DDVI_DEFAULT_SERIAL_CONFIG=waveshare_rp2040_pizero \
.. 

make -j$(nproc)
```

cmake後のビルドオプション
- `-DPICO_SDK_PATH`=/path/to/sdk
  - pico-sdkの場所を入力
- `-DPICO_PLATFORM`=rp2350 
  - デフォルト: rp2040
  - オプションに含めない場合はデフォルトが自動選択される
- `-DPICO_COPY_TO_RAM`=1
  - DVI機能を使用する際は必要
  - ここに記載あり→[Building](https://github.com/Wren6991/PicoDVI/tree/master/software#building)
- `-DDVI_DEFAULT_SERIAL_CONFIG`=pico_sock_cfg
  - DVI出力に使用するボードの設定情報を選択する
  - ここに記載あり→[#support-for-different-boards](https://github.com/Wren6991/PicoDVI/tree/master/software#support-for-different-boards)
  - Waveshare RP2040-PiZeroなら 
    - `-DDVI_DEFAULT_SERIAL_CONFIG=waveshare_rp2040_pizero`
  - Pimoroni Pico DV Demo HDMIなら
    - `-DDVI_DEFAULT_SERIAL_CONFIG=pimoroni_demo_hdmi_cfg`

# ボードに書き込み

makeコマンド実施後、buildディレクトリ以下のappsに格納されている`.uf2`を書き込む
↓キャプチャーボードで`tiles_parallax.uf2`の映像を取り込んだ様子
![スクリーンショット 2024-11-23 17.38.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/c3585508-9c27-6232-ae2c-aa7428e87aa2.png)

↓キャプチャーボードで`hello_dvi.uf2`の映像を取り込んだ様子
![スクリーンショット 2024-11-23 17.41.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/fd335699-e42b-6da0-9004-12a10fdfb397.png)

↓キャプチャーボードで`sprite_bounce.uf2`の映像を取り込んだ様子
![スクリーンショット 2024-11-23 17.42.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/650e7542-fa63-f8f9-451d-72e3ba7a6cc5.png)

↓キャプチャーボードで`tiles_and_sprites.uf2`の映像を取り込んだ様子
![スクリーンショット 2024-11-23 17.43.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/582b1130-2b78-e721-ebce-ad84b8e838e3.png)

↓キャプチャーボードで`christmas_snowflakes.uf2`の映像を取り込んだ様子
![スクリーンショット 2024-11-23 17.44.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/5e2b55eb-ca89-d4f2-28bd-cb3d8dac5b21.png)



# おまけ 
## bad_apple

### 事前準備

#### コード書き換え
`uf2conv`から`picotool`を使用するように変更

`PicoDVI/software/apps/bad_apple/video/mkframes.sh`
```diff
#!/bin/bash
set -ex

rm -rf raw rle pack.bin pack.uf2

mkdir raw
ffmpeg \
	-ss 00:00:05.5 -to 00:00:12.5 \
	-i src.mkv \
	-f lavfi -i color=gray:s=1920x1080 \
	-f lavfi -i color=black:s=1920x1080 \
	-f lavfi -i color=white:s=1920x1080 \
	-filter_complex "threshold,fps=30,crop=1440:1080:240:0,scale=960x720" \
	raw/frame%04d.png

mkdir rle
make -f packframes.mk -j$(nproc)

cat $(find rle -name "*.bin" | sort) > pack.bin

- #uf2conv -f rp2040 -b 0x10010000 pack.bin -o pack.uf2
+ picotool uf2 convert pack.bin -t bin pack.uf2
```

もし、picotoolでエラーになる場合は、下記を参考にpicotoolをビルドしパスに追加してください。
https://forums.raspberrypi.com/viewtopic.php?t=358951#p2152829

#### 再生する動画の準備

`PicoDVI/software/apps/bad_apple/video`以下に`src.mkv`のファイル名で配置

#### ビルドToolのインストール

```
cd work_dir/PicoDVI/software/apps/bad_apple/video

sudo apt install ffmpeg

python3 -m venv picoenv
source picoenv/bin/activate
pip install Pillow
```

#### ビルド

```
./mkframes.sh
```

#### 書き込み手順

1.`work_dir/PicoDVI/software/build/apps/bad_apple`にある、`bad_apple.uf2`を書き込み
2.`work_dir/PicoDVI/software/apps/bad_apple/video`にある`pack.uf2`を書き込み

↓`bad_apple.uf2`で`pack.uf2`を再生した様子
![スクリーンショット 2024-11-23 20.26.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/97af2c34-f0c2-b08a-b4bb-8ca4722fe397.png)