Seeed Studio XIAO ESP32C3 で .NET nanoFramework を動かす

2022年11月16日に .NET nanoFramework が ESP32C3 に対応したようなので試してみたいと思います。なお基本的には公式の [Getting Started Guides](https://docs.nanoframework.net/content/getting-started-guides/getting-started-managed.html) 通りに進めれば動作しますが微妙に手直ししてあります。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Firmware images of .NET <a href="https://twitter.com/nanoFramework?ref_src=twsrc%5Etfw">@nanoFramework</a> for <a href="https://twitter.com/EspressifSystem?ref_src=twsrc%5Etfw">@EspressifSystem</a> ESP32-C3 series have just been released! 🥳🚀<br>.NET now runs on <a href="https://twitter.com/risc_v?ref_src=twsrc%5Etfw">@risc_v</a> processors too!<br>How cool is this?!?! 💜🤩<a href="https://twitter.com/hashtag/dotnet?src=hash&amp;ref_src=twsrc%5Etfw">#dotnet</a> <a href="https://twitter.com/hashtag/esp32c3?src=hash&amp;ref_src=twsrc%5Etfw">#esp32c3</a> <a href="https://twitter.com/hashtag/esp32?src=hash&amp;ref_src=twsrc%5Etfw">#esp32</a> <a href="https://twitter.com/hashtag/iot?src=hash&amp;ref_src=twsrc%5Etfw">#iot</a> <a href="https://twitter.com/hashtag/embeddedsystems?src=hash&amp;ref_src=twsrc%5Etfw">#embeddedsystems</a> <a href="https://t.co/FU1PVAszDu">pic.twitter.com/FU1PVAszDu</a></p>&mdash; .NET nanoFramework (@nanoFramework) <a href="https://twitter.com/nanoFramework/status/1592849360794312704?ref_src=twsrc%5Etfw">November 16, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 必要なもの

| 部品 | 説明|
|:-------------|------------------------|
| XIAO ESP32C3 | [秋月電子](https://akizukidenshi.com/catalog/default.aspx)や[スイッチサイエンス](https://www.switch-science.com/)、[マルツパーツ](https://www.marutsu.co.jp/)、[STEAM Tokyo ストア](https://steam-tokyo.com/store/)などで売ってます |
| USB Type-C ケーブル | 電源供給とファームウェアを書き込むのに必要です |
| USB シリアル | ファームウェア書き込み後はUART0で通信を行うため必要です |
| LED | Lチカ用の LED、なお ESP32C3 には LED は搭載されいません |
| 抵抗 | LED に合わせて適当な150Ωくらいを用意 |

# Visual Studio をインストール
まず [Visual Studio の公式サイト](https://visualstudio.microsoft.com/ja/downloads/)から Visual Studio 2022 をダウンロードします。(コミュニティ版で大丈夫です)
![2022-12-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/89d696cc-ebf6-11a5-3566-5ff39082bca2.png)
ワークロードは .NET デスクトップ開発を選択してインストールします。

:::note info
Getting Started Guides の手順では .NET Core cross-platform development もインストールするように書いてありますが最新では存在しないのでインストールはしません。
:::
![2022-12-31 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/6e20149a-98e3-3dbe-f548-80894d576e6a.png)

# nanoFramework 拡張機能をインストール
プロジェクトの作成は必要ないので「コードなしで続行」で Visual Studio を起動します。
![2022-12-31 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/67a007d3-7593-7485-d52e-24de671ce5c0.png)
メニューの「拡張機能」から「拡張機能の管理」を選択します。
![2023-01-02 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/ce384c02-f4c1-9261-cd72-eebfd0d4fc8d.png)
左側のオンラインを選択して右上の検索ボックスに nanoFramework と入力すると検索結果に .NET nanoFramework Extension が表示されるのでダウンロードしてインストールします。
![2022-12-31 (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/0b31c799-f437-9f79-fd9c-765a0b0c7029.png)
インストールしたら反映させるため Visual Studio を再起動します。（自分の場合はうまく反映されなかったので Windows も再起動しました）

# nanoFirmwareFlasher を使用して ESP32C3 にファームウェアをアップロード
メニューの「表示」から「ターミナル」を起動して nanoff をインストールします。
![2023-01-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/0d40a17b-f8b0-2127-921c-5a023934414c.png)
```
dotnet tool install -g nanoff
```
ESP32C3 とパソコンを USB Type-C ケーブルで接続して「コンピューターの管理」の「デバイスマネージャー」などから ESP32C3 のシリアルポートを探してファームウェアをアップロートします。（COM3 は自分の環境のシリアルポートなのでそれぞれのシリアルポートに読み替えてください）
```
nanoff --platform esp32 --serialport COM3 --update
```
フォームウェアをアップロード後は通信は UART0 になるので USB シリアルを接続してください。
接続方法については [Seeed Wiki](https://wiki.seeedstudio.com/XIAO_ESP32C3_Pin_Multiplexing/) を参考にしてください。
![ESP32C3-serial.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/6ebcb0e4-c41b-8bbd-1223-89c57daeab30.png)
なお Tera Term などでシリアル通信を見ると化けて見えますが問題ありません。
```
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x3fcd5810,len:0x1388
load:0x403cc710,len:0x8d4
load:0x403ce710,len:0x2b78
SHA-256 comparison failed:
Calculated: e35b720346760bc26f1d0a4548cae1b31d07d80b7cc998b440feb718edb617b1
Expected: b4fc3161e3bacb10d4c357f59eaae49c6c9f38957091749f41bb1bc88b287fdb
Attempting to boot anyway...
entry 0x403cc710
I (48) boot: .NET nanoFramework 2nd stage bootloader ESP-IDF 6407ecb
I (49) boot: build Dec 23 2022 01:14:04
I (49) boot: chip revision: 3
I (52) boot.esp32c3: SPI Speed      : 40MHz
I (57) boot.esp32c3: SPI Mode       : DIO
I (62) boot.esp32c3: SPI Flash Size : 4MB
I (67) boot: Enabling RNG early entropy source...
I (72) boot: Partition Table:
I (76) boot: ## Label            Usage          Type ST Offset   Length
I (83) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (90) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (98) boot:  2 factory          factory app      00 00 00010000 001a0000
I (105) boot:  3 deploy           Unknown data     01 84 001b0000 001f0000
I (113) boot:  4 config           Unknown data     01 82 003c0000 00040000
I (120) boot: End of partition table
I (125) esp_image: segment 0: paddr=00010020 vaddr=3c0c0020 size=28e78h (167544) map
I (169) esp_image: segment 1: paddr=00038ea0 vaddr=3fc90600 size=024dch (  9436) load
I (178) esp_image: segment 2: paddr=0003b384 vaddr=40380000 size=04c94h ( 19604) load
I (183) esp_image: segment 3: paddr=00040020 vaddr=42000020 size=bd074h (774260) map
I (352) esp_image: segment 4: paddr=000fd09c vaddr=40384c94 size=0b818h ( 47128) load
I (370) esp_image: segment 5: paddr=001088bc vaddr=50000000 size=00028h (    40) load
I (375) boot: Loaded app from partition at offset 0x10000
I (375) boot: Disabling RNG early entropy source...
I (390) cpu_start: Pro cpu up.
I (399) cpu_start: Pro cpu start user code
I (399) cpu_start: cpu freq: 160000000
I (400) cpu_start: Application information:
I (402) cpu_start: Project name:     nanoCLR
I (407) cpu_start: App version:      1.8.0.858
I (412) cpu_start: Compile time:     Dec 23 2022 01:13:36
I (418) cpu_start: ELF file SHA256:  6d7836f600db76c2...
I (424) cpu_start: ESP-IDF:          6407ecb
I (429) heap_init: Initializing. RAM available for dynamic allocation:
I (437) heap_init: At 3FC9B970 len 00040DA0 (259 KiB): DRAM
I (443) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM
I (449) heap_init: At 50000028 len 00001FD8 (7 KiB): RTCRAM
I (457) spi_flash: detected chip: generic
I (461) spi_flash: flash io: dio
I (476) sleep: Configure to isolate all GPIO pins in sleep state・BB堆BB
```
Visual Studio で接続を確認するにはメニューの「表示」から「その他のウィンドウ」から「Device Explorer」を選択します。
![2023-01-02 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/968663ab-f0d5-db26-40fd-4cfbeed3da0c.png)
接続が成功すれば Devices に表示されます。
![2023-01-02 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/b709671b-adc5-e87c-8718-4d1c224e336b.png)
表示されない場合は虫眼鏡アイコンの「Rescan nanoDevices」か ESP32C3 のリセットを試してください。
![PXL_20230103_190959564.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/51b5f851-37bd-1e5d-7767-badc9c85ec03.png)


# Lチカ
メニューの「ファイル」から「新規作成」から「プロジェクト」で新しいプロジェクトを作成します。
![2023-01-02 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/26f49bac-fbd5-e8de-ce63-f9f43d056ce5.png)
検索ボックスに nanoFramework と入力すると Blank Application (.NET nanoFramework) というテンプレートが表示されるはずなので選択します。
![2023-01-02 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/f4bddaa1-c110-b4cc-e214-23b88dbed3c0.png)
[.NET nanoFramework サンプル](https://github.com/nanoframework/Samples/tree/main/samples/Blinky)に合わせて Blinky プロジェクトを作成します。
![2023-01-02 (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/97243108-1744-0036-0eee-8d847dfd1c13.png)
プログラムはピン番号を ESP32C3 に合わせて変更して [Seeed Wiki](https://wiki.seeedstudio.com/XIAO_ESP32C3_Getting_Started/) に合わせました。
```Program.cs
using System;
using System.Threading;
using System.Device.Gpio;

namespace Blinky
{
    public class Program
    {
        private static GpioController s_GpioController;

        public static void Main()
        {
            s_GpioController = new GpioController();

            // ESP32C3
            GpioPin led = s_GpioController.OpenPin(10, PinMode.Output);

            led.Write(PinValue.Low);

            while (true)
            {
                led.Toggle();
                Thread.Sleep(1000);
                led.Toggle();
                Thread.Sleep(1000);
            }
        }
    }
}
```
NuGet で Gpio のクラスライブラリを取得するためソリューションエクスプローラーの参照を右クリックして「NuGet パッケージの管理」を選択します。
![2023-01-02 (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/73418b4b-d3ed-9748-234f-463d335fb953.png)
検索ボックスに nanoFramework と入力して nanoFramework.System.Device.Gpio パッケージを探してインストールします。
![2023-01-02 (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/52326057-b3c8-183d-ec50-d6a3bdd42dfe.png)
ビルドできる準備が整ったのでメニューの「ビルド」から「Blinky のビルド」でビルドします。
![2023-01-02 (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/8e2fa182-5bbd-51ff-4bad-a87530e6ddbd.png)
ビルドができたらデバイスに配置（デプロイ）するためメニューの「ビルド」から「Blinky の配置」を選択します。なお配置した場合はデバイスをリセットしないとアプリが実行されません。（デバッグ実行の場合はリセットが不要です）
![2023-01-02 (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252533/3df1f64a-5107-9292-1bfa-b44bd5735ff9.png)

# 最後に
けっこう簡単にLチカができました。
暇があったら他のペリフェラルも試してみたいと思います。
以下に今回のサンプルプログラムを置いておきます。
https://github.com/k-mana/esp32c3-nanoframework