ラズピコのMicroPythonからILI9341 TFT液晶を使う

# 概要
Raspberry Pi Picoは、MicroPythonを簡単に動作させてすぐにプログラムを動かすことができます。しかし、MicroPythonでは周辺機器の制御については多くの処理を自力で組み込む必要があります。また、日本語表示をするためには、かなりの工夫が必要になります。

そこで、以前公開した[Rapberry PI Pico(標準SDK/ArduinoSDK) 用　ILI9341 TFT液晶 日本語ライブラリ](https://qiita.com/BUBUBB/items/7c6777c04dedf01d7c3b)　を、Micropytonから使用できるようにするため、ユーザーCモジュールとしてビルドしました。

日本語フォントは、MicroPythonファームウェア(firmware.uf2)の一部として組み込まれます。バイナリ形式でフラッシュメモリ上に保持されるため、メインメモリへの圧迫は少なくなります。

Pythonからは数行でILI9341液晶コントローラーが制御できます。

```
import KNJGfx
    
KNJGfx.setDebugMode(1)
KNJGfx.initHW((0,20,22,18,19,21,0))
KNJGfx.setRotation(3)
KNJGfx.fillScreen(0, 0x00FF)
KNJGfx.loadDefaultKanjiFont(0)
KNJGfx.setCursor(0,10,30)

KNJGfx.print(0,"こんにちは")
```

# ハードウェア

[Rapberry PI Pico(標準SDK/ArduinoSDK) 用　ILI9341 TFT液晶 日本語ライブラリ](https://qiita.com/BUBUBB/items/7c6777c04dedf01d7c3b#%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2)　の、使用するまでの準備＞ハードウェアを参照し、結線してください。

- Raspberry PI Picoの右半分に線が集中するようにしてあります
- 変更は可能ですが、```KNJGfx.initHW((0,20,22,18,19,21,0))``` の部分に使用するピン番号を指定する必要があります

# ビルド済みイメージを使用する

ビルド済みのイメージを使用する場合は、次の手順に従って作業してください。

## MicroPythonのダウンロード

[Githubのリポジトリページ](https://github.com/HisayukiNomura/KNJGfx9341)に行き、右側にある[Releses をクリック](https://github.com/HisayukiNomura/KNJGfx9341/releases)、最新のリリースを表示させます。

preBuild_MycroPy.zipをダウンロードしてください。

<img width=60% alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/287fab54-2523-4fa5-8f11-c883f337b10d.png">

## 必要なファームウェアを選定

ZIPファイルの中には、ボードの種類/フォルダ、とディレクトリごとに別れており、それぞれのフォルダの中には firmware.uf2が含まれています。

```
/
├─── Build-PICO .... Raspberry Pi Pico (無印）用
│　　　│
│　　　├───　build-RPI_PICO_12L1 .... 東雲フォント12ドットゴシック、JIS第一水準
│　　　├───　build-RPI_PICO_14L1 .... 東雲フォント14ドットゴシック、JIS第一水準
│　　　├───　build-RPI_PICO_16L1 .... 東雲フォント16ドットゴシック、JIS第一水準
│　　　├───　build-RPI_PICO_24GL1.... IPAフォント24ドットゴシック、JIS第一水準
│　　　└───　build-RPI_PICO_24ML1.... IPAフォント24ドット明朝、JIS第一水準
│ 
├─── Build-PICO2 .... Raspberry Pi Pico ２用
│　　　│
│　　　├───　build-RPI_PICO_12L1 .... 東雲フォント12ドットゴシック、JIS第一水準
│ 　　 ：                  :
│ 　　 ：                  :
│　　　└───　build-RPI_PICO_24ML1.... IPAフォント24ドット明朝、JIS第一水準
│
├─── Build-PICOW .... Raspberry Pi Pico W　用
│　　　　　　　：
│　　　　　　　：
└── Build-PICO2W .... Raspberry Pi Pico ２W　用
　　　　　　　　：
　　　　　　　　：
```

この中から、必要な firmware.uf2を選択してください。

たとえば、手持ちのボードが Raspberry PI Pico 2で、16ドットフォントを使用したいという場合、```build-PICO2\build-RPI-PICO2_16L1```フォルダの中にあるfirmware.uf2を使用します。

ボードと、フォント、フォントのセットの組み合わせは膨大になってしまうため、代表的なものだけを含めています。異なる組み合わせ、例えば、１６ドットでＪＩＳ第二水準を含めたい、などの場合、後述の手順に従ってMicropythonをビルドする必要があります。ビルドが難しいという場合、作者に連絡をお願いします。時間があればビルドしてみます。

## ファームウェアのインストール

Raspberry PI Picoのボタンを押しながら、USBを差し込みます。マスストレージデバイスとして認識されるので、firmware.uf2をコピーしてください。

コピーが完了すると、自動的にマスストレージデバイスは切断されます。

## Thonny の起動と実行

この説明では、ThonnyでPythonを実行することを前提として説明しています。Thonnyの使い方については、インターネットなどで確認してください。
Visual Studio Code （標準SDK）のmicroPython環境を使用している場合、適宜読み替えてください。Raspberry PI Pico側に、ファームウェアが導入済みであれば基本的に実行することは変わりません。

次のプログラムを入力し、実行ボタンを押してください。

```
import KNJGfx
    
KNJGfx.setDebugMode(0)
KNJGfx.initHW((0,20,22,18,19,21,0))
KNJGfx.setRotation(3)
KNJGfx.fillScreen(0, 0x00FF)
KNJGfx.loadDefaultKanjiFont(0)
KNJGfx.setCursor(0,10,30)

KNJGfx.print(0,"こんにちは")
```

<img width=40% alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/d526ee86-17c9-43bd-9eb0-4179c902c093.png">

液晶画面には、青地に白文字で「こんにちは」と表示されます。この画像は、２４ドット明朝を使用しています。
<img width=50% alt="2.png" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/0dfdab1a-9611-4f9a-ba48-b89a1f8331e9.png">

各行は、次のような意味を持っています。
- KNJGfx.setDebugMode(0)
デバッグモードを無効にします。1を指定すると、実行した命令がそのまま標準出力に表示されます。
　
- KNJGfx.initHW((0,20,22,18,19,21,0))
ハードウェアを初期化します。引数がタプルになっていること（かっこが２つ）に注意してください。
引数は次のようになっています。[Rapberry PI Pico(標準SDK/ArduinoSDK) 用　ILI9341 TFT液晶 日本語ライブラリ](https://qiita.com/BUBUBB/items/7c6777c04dedf01d7c3b#%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2)を参照し、結線にあわせて指定してください。
　
　０・・SPIチャンネル(0または1)
２０・・DC…TFTのデータ/コマンドポート番号
２２・・CS…デバイスセレクト、
１８・・CSK…クロック
１９・・MOSI…マスタ⇒スレーブ信号線
２１・・Reset…リセット信号
　０・・Debug…デバッグポート番号（未使用。ゼロを指定）
　
- KNJGfx.setRotation(3)
画面の回転方向を指定します。０（端子側短辺を下）、１（端子側短辺を右）、２、３が指定できます。
-KNJGfx.fillScreen(0, 0x00FF)
画面をカラーコード0x00FFで塗りつぶします。引数は次のようになっています。
　
０・・対象の画面番号。０が、物理的に接続されているTFT液晶です。１～３２は、オンメモリに確保するキャンバスに対して描画します。キャンバス機能については実際のサンプルプログラムで確認してください。
０ｘ００ＦＦ・・塗りつぶす色です。フォーマットはRGBGの565です。（赤が0xF800,緑が0x07E0,青が0x001F)
　
- KNJGfx.loadDefaultKanjiFont(0)
漢字コードを読み込みます。対象の画面番号を指定します。０が、物理的に接続されているTFT液晶です。
　
- KNJGfx.setCursor(0,10,30)
表示位置を指定します。最初の０は画面番号、次の２つがＸＹ位置です。座標は、(0,(10,30))のようにタプルとして渡すことができます。原則として、このプログラムでは座標などはタプルとして扱いますが、setCursorだけは特別に、独立した引数として渡すことができます。（作っている最中に毎回間違えたのでここだけ対応した）
　
- KNJGfx.print(0,"こんにちは")
画面にテキストを表示します。

# 高度なサンプルプログラムを使用する
文字表示以外の描画を行うサンプルプログラムは次のURLからダウンロードできます。

[GithubのExamplesサブフォルダ](https://github.com/HisayukiNomura/KNJGfx9341/tree/main/lib-9341/ForMPY/Examples)

ここから、test9341.py　と、BitmapDataサブフォルダをダウンロードします。

BitmapDataサブフォルダには、ビットマップ画像のデータなどが含まれています。

BitmapDataサブフォルダの内容を、事前に RaspberryPI Picoに転送しておいた上で、test9341.pyを実行します。

## データの転送
一般的な方法として、ThonnyでBitmapサブフォルダに含まれる .py ファイルを開き、保存先をRaspberry Pi PicoにすることでファイルをPicoに転送できます。この方法が使用できる場合、この方法でBitmapDataサブフォルダにあるファイルをすべて、Picoに転送してください。

<img width=40% alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/f17c9d0b-9a25-441c-81ea-b21a26386266.png">

私の環境ではなぜか、ファイルサイズが大きくなると転送に失敗してしまいます。そのため、rshellを使用してファイルを転送します。説明は、より「めんどくさい」Windowsをベースにしています。linuxを使用している場合適宜読み替えてください。（一般的に、windowsよりlinuxの方が簡単です）

- pythonとpipがインストールされていることを確認します。<br/>
```
e:\work>python --version
Python 3.13.3

e:\work>pip --version
pip 25.1.1 from <site-packagesの場所>\pip (python 3.13)
```
- pipを使用してrshellを導入します。
```
e:\work>pip install rshell
Defaulting to user installation because normal site-packages is not writeable
Collecting rshell
    :
    :
Cache\local-packages\Python313\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pyreadline-2.1 pyudev-0.24.3 rshell-0.0.36
```
- rshellが動作するかを確認します。
```
rshell --help
```

Windowsの場合、rshellは、通常、自動的に exe 形式になりインストールされています。
例：C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\Scripts\rshell.exe
rshellが起動できない場合、PC内を検索し、pathを通してください。

rshellがインストール出来たらThonnyを終了し、cpコマンドを使用してコピーしてください。

```
rshell [-p ポート番号 --buffer-size=8192] cp <サンプルのpythonがあるフォルダ>/*.py /pyboard/
```
ポート番号と--buffer-sizeに大きめの値を指定すると速度が速く安定します。また、フォルダには、ドライブを除く絶対パスを、/ を区切り記号として指定します。このツール自体がlinuxを前提としているためWindowsでは使いにくさが残ります。

たとえば、Raspberry PIがCOM17 に接続されており、転送するファイルがE:\hoge\BitmapData\の中にある場合、次のようなコマンドになります。

```
rshell -p COM17 --buffer-size=8192 cp /hoge/BitmapData/*.py /pyboard/

Using buffer-size of 8192
Connecting to COM17 (buffer-size 8192)...
Trying to connect to REPL  connected
Retrieving sysname ... rp2
Testing if ubinascii.unhexlify exists ... Y
Retrieving root directories ...
Setting time ... May 22, 2025 10:01:34
Evaluating board_name ... pyboard
Retrieving time epoch ... Jan 01, 1970
Copying '/hoge/BitmapData/Apr1.py' to '/pyboard/Apr1.py' ...
　　　　：
Copying '/hoge/BitmapData/Sep1.py' to '/pyboard/Sep1.py' ...
```
## サンプルプログラムの実行

転送が完了したら、Thonnyを起動し、test9341.py　を読み込みます。
画面には、Pico側にデータファイルが転送されていることが確認できます。
確認が終わったらプログラムを実行してください。

<img width=40% alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/545a9853-cdf3-4a91-9b2d-8e3e2aea325a.png">

基本的な図形の描画、ビットマップの表示、キャンバスの利用などのサンプルが実行されます。
|ビットマップ|キャンバス|基本図形|透過表示|
|-------|------|--------|------|
|<img width=100% alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/dec6c8f1-3952-4b1a-a8ca-e1538d8a4a32.png">|<img width=100% alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/3b37121d-de45-4fbe-bd52-eb3a11c2ab48.png">|<img width=100% alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/25b8247e-5632-4c8c-8e39-5d309e0d2989.png">|<img width=100% alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/5e8ae114-0122-4731-ab01-39c5dd2f47fd.png">|


# Micropython C拡張モジュール 関数リファレンス

## 引数の凡例
### 液晶表示関連
|仮引数名|説明|
|--------|------|
|a_Target|対象の画面番号。０が物理的に接続されているTFT液晶。１～３２はメモリ上に確保されているキャンバス(オフスクリーンメモリ）|
|a_tf|True、もしくはFalseを指定|
|a_Rotation|画面の回転角度。０（端子側短辺を下）、１（端子側短辺を右）、２（端子側短辺を上）、３（端子側短辺を左）|
|a_top,a_bottom|スクロール時に除外する上下エリアの大きさ|
|a_x|Ｘ座標|
|a_y|Ｙ座標|
|a_color,a_bgColor|色指定。フォーマットはRGBGの565。（赤が0xF800,緑が0x07E0,青が0x001F)|
|a_xy|Ｘ座標、Ｙ座標を含むTupple。(x,y)として指定する|
|a_xyl|Ｘ座標、Ｙ座標、長さ（幅や高さなど）を含むTupple。(x,y,l)として指定する|
|a_xywh|Ｘ座標、Ｙ座標、幅、高さを含むTupple。(x,y,w,h)として指定する|
|a_xyxy|二つのＸ座標、Ｙ座標を含むTupple。(x1,y1,x2,y2)として指定する|
|a_xyxy|三つのＸ座標、Ｙ座標を含むTupple。(x1,y1,x2,y2,x3,y3)として指定する|
|a_xyr|Ｘ座標、Ｙ座標、半径を含むtupple。(x,y,r)として指定する|
|a_xyxyr|二つのＸ座標、Ｙ座標と半径を含むTupple。(x1,y1,x2,y2,r)として指定する|
|a_xywhr|Ｘ座標、Ｙ座標、幅、高さ、半径を含むTupple。(x,y,w,h,r)として指定する|
|a_str|文字列を指定する|
|a_size|文字の拡大率を指定する。２を指定すると文字は２倍の大きさで表示される|
|a_canvasID|キャンバス（オフスクリーンメモリ）の番号を指定します。１～３２が指定できます。使用前にはキャンバスを作成してから使用します|
|a_keyColor|キーカラーを指定します。キーカラーに指定された色は、ビットマップ表示などでは透明色として扱われます|

### 画面のタッチ関連
|仮引数名|説明|
|--------|------|
|a_cs|タッチスクリーンのCSを指定します。|
|a_IRQ|タッチスクリーンの割り込みポートを指定します。２５５の場合未使用です|
|a_minmax|X座標、Y座標の最大、最小値を指定します|
|a_Rotation| TFT液晶の説明を参照してください|




## 初期化・設定関数
| 関数名 | 説明 |
|--------|------|
| `initHW((spi,dc,cs,csk,mosi,Reset,Debug))` | ハードウェアの初期化を行います。<br/>SPIチャンネル<br/>DC…TFTのデータ/コマンドポート番号<br/>CS…デバイスセレクト<br/>CSK…クロック<br/>MOSI…マスタ⇒スレーブ信号線<br/>Reset…リセット信号<br/>Debug…デバッグポート番号（未使用。ゼロを指定）|
| `setDebugMode(a_mode)` | デバッグモードを設定します。0...デバッグ表示なし、1...デバッグ表示あり |
| `loadDefaultKanjiFont(a_Target)` | デフォルトの漢字フォントをロードします |
| `loadDefaultAsciiFont(a_Target)` | デフォルトのASCIIフォントをロードします |
| `setRotation(a_Rotation)` | ディスプレイの回転を設定します |
| `displaySleep(a_tf)` | ディスプレイのスリープを制御します |

## 特殊描画関数
| 関数名 | 説明 |
|--------|------|
| `invertDisplay(a_tf)` | 画面の色を反転します |
| `setScrollMargins(a_top, a_bottom)` | スクロール範囲の上下マージンを設定します |
| `scrollTo(a_y)` | 指定したY座標へスクロールします |

## 基本描画関数
| 関数名 | 説明 |
|--------|------|
| `fillScreen(a_Target, a_color)` | 画面を指定色で塗りつぶします |
| `drawPixel(a_Target, a_xy, a_color)` | 指定座標にピクセルを描画します |
| `drawFastHLine(a_Target, a_xyl, a_c)` | 水平線を描画します |
| `drawFastVLine(a_Target, a_xyl, a_c)` | 垂直線を描画します |
| `fillRect(a_Target, a_xywh, a_color)` | 指定範囲を塗りつぶします |
| `drawRect(a_Target, a_xywh, a_color)` | 長方形を描画します |
| `drawLine(a_Target, a_xyxy, a_color)` | 線を描画します |
| `drawCircle(a_Target, a_xyr, a_color)` | 円を描画します |
| `fillCircle(a_Target, a_xyr, a_color)` | 円を塗りつぶします |
| `drawRoundRect(a_Target, a_xywhr, a_color)` | 角丸の長方形を描画します |
| `fillRoundRect(a_Target, a_xywhr, a_color)` | 角丸の長方形を塗りつぶします |
| `drawTriangle(a_Target, a_xyxyxy, a_color)` | 三角形を描画します |
| `fillTriangle(a_Target, a_xyxyxy, a_color)` | 三角形を塗りつぶします |

## テキスト描画関数
| 関数名 | 説明 |
|--------|------|
| `setCursor(a_target,a_xy)` | テキストカーソルの位置を設定します |
| `setCursor(n_args,a_x,a_y)` | テキストカーソルの位置を設定します |
| `print(a_Target, a_str)` | テキストを描画します |
| `setTextWrap(a_Target, a_tf)` | テキストの折り返しを設定します |
| `setTextForegroundColor(a_Target, a_color)` | テキストの前景色を設定します |
| `setTextBackgroundColor(a_Target, a_color)` | テキストの背景色を設定します。背景色と前景色が同じ場合、その文字は背景透過となります|
| `setTextColor(a_Target, a_color, a_bgcolor)` | テキストの前景色と背景色を設定します。背景色と前景色が同じ場合、その文字は背景透過となります| |
| `setTextSize(a_Target, a_size)` | テキストのサイズを設定します。２を指定すると文字の大きさは２倍になります |
| `setKanjiMode(a_Target, a_tf)` | 漢字モードを設定します。漢字モードが有効な場合、ASCII文字を含むすべての文字は日本語フォントとして描画されます。Falseを指定すると、ASCII文字はデフォルトのアスキーフォントとして描画されます。この場合日本語は表示されません。 |
| `setKanjiFont(a_Target, a_code, a_bitmap)` | 未実装です。フォントデータをPython側に持って指定するようにしましたが、メモリが圧倒的に足りないため実装は困難です。 |

## ビットマップ関数
| 関数名 | 説明 |
|--------|------|
| `drawBitmap(a_Target, a_xywh, a_bitmap)` | 指定座標にビットマップを描画します |
| `drawBitmapWithKeyColor(a_Target,a_xywh,a_bitmap,a_keyColor)` | キーカラー付きでビットマップを描画します。キーカラーに指定された色は、透明色として描画されるので背景がそのまま残ります |
| `drawBitmapFromCanvas(a_Target, a_xy, a_canvasID)` | キャンバスからビットマップを描画します |

## キャンバス関数
| 関数名 | 説明 |
|--------|------|
| `createCanvas(a_wh)` | キャンバスを作成します。戻り値には作成されたキャンバスのIDが１～３２で戻されます。このキャンバスに対して、画面と同じように描画することができます。作成したキャンバスはビットマップ転送で画面に表示できます。 |
| `deleteCanvas(a_canvasID)` | キャンバスを削除します。|
| `setCanvasKeyColor(a_canvasID, a_keycolor)` | キャンバスのキーカラーを設定します。ここで指定した色は、ビットマップで画面に表示するときに透明色として扱われます |
| `resetCanvasKeyColor(a_canvasID)` | キーカラーをリセットします |

## タッチ関数
| 関数名 | 説明 |
|--------|------|
| `initTouchHW(a_CS, a_IRQ)` | タッチハードウェアを初期化します。IRQを使用しない場合255を指定します。 |
| `setTouchCalibrationValue(a_minmax)` | タッチのキャリブレーション値を設定します。 |
| `setTouchRotation(a_Rotation)` | タッチ回転を設定します。通常、TFTと同じ値を指定します。 |
| `beginTouch()` | タッチ操作を開始します |
| `isTouch()` | タッチされているかを確認します。タッチされている場合、Trueが返されます。getTouchXYでタッチされている座標を取得します。|
| `getTouchRawXYZ()` | タッチの生データを取得します。キャリブレーションを行うときに使用します。 |
| `getTouchXY()` | タッチ座標を取得します。XYのタプルが返されます |


# タッチパネルのキャリブレーションについて
小ロット生産者とともに歩む秋月電子の[ILI9341搭載2.8インチSPI制御タッチパネル付TFT液晶MSP2807](https://akizukidenshi.com/catalog/g/g116265/)では、XPT2046がコントローラとして付属しています。このコントローラーはキャリブレーションが必要で、キャリブレーションを行わない場合タッチ位置が微妙にずれてしまいます。

多少のずれを問題にしないため、多くのサンプルではデフォルトの値のまま使用しています。このライブラリでも、私が購入した製品で行ったキャリブレーション値をデフォルトとして使用しています。

あまり精密な操作は要求されないため、多くの場合デフォルトでも問題ありませんが、タッチ位置のズレが気になる人は、次のようなコードで購入したデバイスにあわせた値を求め、setTouchCalibrationValue(a_minmax)で調整してから使用してください。
```
import KNJGfx
import time
import random

def Touch10():
    count = 0
    minx = 99999
    miny = 99999
    maxx = 0
    maxy = 0
    
    while True:
        if KNJGfx.isTouch():
            rawpos = KNJGfx.getTouchRawXYZ()
            pos = KNJGfx.getTouchXY()
            KNJGfx.fillCircle(0,(pos[0],pos[1],5),random.randint(0,0xFFFF))
            minx = rawpos[0] if (minx > rawpos[0]) else minx
            miny = rawpos[1] if (miny > rawpos[1]) else miny
            maxx = rawpos[0] if (maxx < rawpos[0]) else maxx
            maxy = rawpos[1] if (maxy < rawpos[1]) else maxy
            count = count + 1
        if count > 10 :
            return [minx,miny,maxx,maxy]
        time.sleep(0.1)


def main():
    # 初期化処理    
    KNJGfx.setDebugMode(0)
    KNJGfx.initHW((0,20,22,18,19,21,0))
    KNJGfx.setRotation(3)
    KNJGfx.loadDefaultKanjiFont(0)

    KNJGfx.initTouchHW(17,255)
    KNJGfx.setTouchRotation(3)
    KNJGfx.beginTouch()

    # 左上の最小値を求める
    KNJGfx.fillScreen(0, 0x00FF)
    KNJGfx.setCursor(0,10,10)
    KNJGfx.setTextColor(0,0xFFFF,0xFFFF)
    KNJGfx.print(0, "画面左上をタップ")
    rawPos = Touch10()
    minX = rawPos[0]
    minY = rawPos[1]
    
    #右下の最小値を求める
    KNJGfx.fillScreen(0, 0xFF0)
    KNJGfx.setCursor(0,100,210)
    KNJGfx.setTextColor(0,0x0000,0x0000)
    KNJGfx.print(0, "画面左下をタップ")
    rawPos = Touch10()
    maxX = rawPos[2]
    maxY = rawPos[3]

    KNJGfx.fillScreen(0, 0x00FF)
    KNJGfx.setTextColor(0,0xFFFF,0xFFFF)
    KNJGfx.setCursor(0,10,10)
    
    #結果を画面に表示する
    KNJGfx.print(0,f"min: {minX},{minY}\r\n")
    KNJGfx.print(0,f"max: {maxX},{maxY}\r\n")

    print(f"KNJGfx.setTouchCalibratonValue(({minX},{minY},{maxX},{maxY}))")
    KNJGfx.setTouchCalibrationValue((minX,minY,maxX,maxY))



if __name__ == "__main__":
    main()    
```

実行すると、画面の左上をタップするような指示があります。画面のなるべく左上をタップしてください。タップした箇所には小さい丸が出ます。画面の外をタップすると無効ですが、気にせずなるべく外側を連打してください。
１０回、タッチが認識されると画面の色が変わり、今度は左下をタップするように指示があります。同様にタップしてください。

終了すると、画面には最小値、最大値が表示されます。この値を、`KNJGfx.setTouchCalibratonValue(({minX},{minY},{maxX},{maxY}))`のように呼びだしてください。
標準出力には、`KNJGfx.setTouchCalibratonValue((418,353,3863,3747))` のように実際の呼び出しの方法が示されます。

このキャリブレーションは保存されません。使用するときにはプログラムの先頭で毎回指定してください。


# 自分用にビルドする

使いたいフォントを変更したい、フォントセットを変更したい、機能を強化したい、バグを何とかしたい、などの要望がある場合、Micropythonをビルドすることもできます。


# 環境の準備

この説明では、Windows PC (Windows 10以上）があるものとして準備を進める。しかし、実際の手順はほとんどがWSLを使用した linux上で行われるので、元々linuxでビルドするという場合は、Windows部分を無視すれば問題ない。

## WSLのインストールと環境の構築

※ Linux上にビルド環境を構築する場合は不要

いろいろ試したが、MicroPythonのビルドスクリプトを、Windows上のRaspberry Pi PicoSDKで動かすことができなかった。（クロスコンパイラの環境構成が複雑なこと、CMakeが生成するビルドのレシピ内で、パスの表現形式がWindows (C:\hoge\moge)になってしまうがコンパイラなどのツールがこの形式を受け入れないこと等が原因と思われる。）

そのため、エディタやファイルの管理などではWindowsを使用して、ビルドはWSLのubuntu を使用する方法で環境を作成する。Visusal Studio CodeはシームレスにWSLを使用することができるので、使用感はほとんどWindowsでビルドするのと変わらない。


## WSLのインストール

WSLをインストールし、WSL1.0にバージョンダウンする。すでにWSLを使用している場合でも1.0に戻す必要がある。（1.0に戻しても既存の2.0環境は破壊されない。2.0に戻すことも可能）
WSL 2.0は、Windowsからのファイルシステム操作が1.0よりも極端に遅く、Windowsから編集・ビルドを行うのは事実上使い物にならない。そのため、WSL 1.0を使用する必要がある。

## WSLのインストール
[WSL を使用して Windows に Linux をインストールする方法](https://learn.microsoft.com/ja-
jp/windows/wsl/install)や、[【WSL2セットアップ】Windowsの機能の有効化または無効化]([https://qiita.com/fujinninja/items/8882e179270b144076df)　などを参照し、WSLをインストールする。

インストールが終了したら、Microsoft Storeから、Ubuntu をインストールする。

<img width=60% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/eecd181a-c2bd-40e5-a2d7-550c0404ff3c.png">

インストールが終了したら、スタートメニューから ubuntuを選び、起動する。最初に起動すると、ユーザー名とパスワードを聞かれるので、適当に入力する。次のようなプロンプトが出れば正常。（user / mmachinenameは環境により異なる）
```user@machinename : ~$ ```
確認が終了したら、ubuntuは終了（ログアウト）しておく。


## WSLのバージョン確認とバージョンダウン

もし、現状WSL2がインストールされている場合、WSLに戻す。WSL2は、Windowsのファイルシステム操作が非常に遅くMicroPythonのビルドが２～３時間かかってしまう。WSLの場合、フルビルドの場合でも３０分程度で終了する。

管理者権限のコマンドプロンプトを開き、現在のWSLバージョンを確認する。

```
C:\Windows\System32>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-24.04    Running         2
```

バージョンが1の場合、バージョンダウンは不要。バージョンが２の場合、ディストリビューションを指定してバージョンを１に変換する。変換操作で変換対象のlinux環境がリセットされることはない。変換後にバージョンが１になっていることを確認しておく。（３分以内）

```
C:\Windows\System32>wsl --set-version Ubuntu-24.04 1
変換中です。これには数分かかる場合があります。
この操作を正しく終了しました。

C:\Windows\System32>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-24.04    Running         1
```


## Visual Studio CODEのインストール
Windows側で、Visual Studio Codeをインストールしておく。
**WSL側には、Visual Studio Codeのインストールは必要ないことに注意。**

Visual Studio Codeには次のアドインの導入をしておく。

- WSL。必須。Visual Studio CodeとWSLを連携させ、WSL内のLinux環境で開発を行う<br/><img width=60% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/37a40abf-03bc-4856-8675-8a056e1d3695.png">
- C/C++、Cmake Tools、Python
- Raspberry PI PICO　なくても良いが、あると何かと便利









## 必要なツールのインストール

スタートメニューからubuntuを起動し、ビルドに必要なツールをインストールしていく。
最初に、update/upgradeをしてから、ビルドツールを導入する。（１０分）

必要なものは次の通り。すでに導入済みの場合、この作業は不要。


**WSL側には、Visual Studio Codeのインストールは必要ない(インストールすべきではない）ことに注意。**


|名称|正式名称|概要|
|:--- |:---|:---|
|gcc-arm-none-eabi|GNU Arm Embedded Toolchain|ARM Cortex-MやCortex-Rなどの組み込みプロセッサ向けに設計されたクロスコンパイラツールチェーン|
|libnewlib-arm-none-eabi|Newlib C Library for ARM Embedded Systems|組み込みシステム向け軽量Cライブラリ。Cortex-MやCortex-Rプロセッサ用、stdio、mathなど標準ライブラリを提供。
|build-essential|Build Essential Package|ソフトウェアをビルドするために必要な基本的なツール群。gcc、g++、makeなどが含まれる。|
|cmake|Cross-Platform Make|オープンソースのビルドシステムで、プラットフォームやコンパイラに依存しない構成ツール。|


```
~$ sudo apt update
~$ sudo apt upgrade
~$ sudo apt install gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
~$ sudo apt-get install cmake
```
すべてのツールが非常に一般的なものなので、apt やpacmanなど一般的なパッケージツールでインストールできる。（cmakeは最新版がaptなどでインストールできないが、最新版は不要）



実行例（開発ツール）
```
~$ sudo apt update
 :
~$ sudo apt upgrade
 :
~$ sudo apt install gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
$ sudo apt install gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following package was automatically installed and is no longer required:
   :
   :
Setting up libheif-plugin-libde265:amd64 (1.17.6-1ubuntu4.1) ...
Setting up libheif-plugin-aomenc:amd64 (1.17.6-1ubuntu4.1) ...
Processing triggers for libc-bin (2.39-0ubuntu8.4) ...
Processing triggers for man-db (2.12.0-4build2) ...   
~$
```

実行例（cmake)
```
~$ sudo apt-get install cmake
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
  :
Processing triggers for man-db (2.12.0-4build2) ...
Processing triggers for libc-bin (2.39-0ubuntu8.4) ...
~$ 

```

## ビルドディレクトリの作成とマウント
今回は、Windowsファイルシステム上にビルド用のファイルを作成し、Windowsから編集などのファイル操作をおこない、linux側ではビルドだけ、という形で構成する。
そのため、Windows側でビルドのフォルダを用意し、それをlinux側でマウントし、Windows/Linux双方でファイルにアクセスできるようにしておく。

今回は、E:\Work\PythonMod でビルドを行い、linux側はE:ドライブ全体を、/e にマウントして操作できるように設定する。例えば、Windowsで　e:\work\PythonModは、Linux側からは /e/work/PythonModとしてアクセスできる。

Windows
```
E:\>mkdir work\PythonMod
E:\>cd \work\PythonMod
```

Linux
```
~$ sudo ln -s  /mnt/e/ /e
~$ cd /work/PythonMod
```


## MicroPythonをソースコードからビルドする

### ソースコード取得
/e/work/PythonMod/micropythonディレクトリにおいて、gitから、MicroPythonのソースコードを取得する。この操作で、/e/work/PythonMod/micropythonディレクトリにMicroPythonのソースコードが格納される。

```
 git clone https://github.com/micropython/micropython.git --branch master
```

実行例
```
~$ cd /e/work/PythonMod
/e/work/PythonMod$ git clone https://github.com/micropython/micropython.git --branch master
Cloning into 'micropython'...
remote: Enumerating objects: 127569, done.
   :
/e/work/PythonMod$   
```

### ビルド

ソースコードを取得出来たら、まずはC拡張モジュール無しで、そのままMicroPythonをビルドできるようにしておく。

#### Submoduleのビルド

```make -C ports/rp2 submodules``` 

コマンドを使い、サブモジュールをビルドする。

このとき、ターゲットのボードをビルドの引数で指定する。省略時は、Raspberry Pi Pico無印（BOARD=RPI_PICO と同じ）。
指定可能なビルドターゲットは、…\micropython\ports\rp2\boards　内にフォルダとして含まれている。良く使うだろうと思われるものは次の通り。

|指定する引数|対象デバイス|
|:--- |:---:|
|BOARD=RPI_PICO|Raspberry Pi Pico(デフォルト）|
|BOARD=RPI_PICO_W|Raspberry Pi Pico W|
|BOARD=RPI_PICO2|Raspberry Pi Pico 2|
|BOARD=RPI_PICO2_W|Raspberry Pi Pico2 W|

たとえば 

```make -C ports/rp2 submodules BOARD=RPI_PICO_W ```

などとすれば、Raspberry Pi Pico Wとしてビルドできる。Submoduleに関して言えば、Raspberry Pi PicoとPico 2は互換性があるが、 Raspberry Pi Pico Wなどは、Raspberry Pi Pico WのWi-Fiドライバ（cyw43-driver）を組み込む必要があるので正しいサブモジュールをビルドしておかないと後のビルドでエラーが発生する。

```
/e/work/PythonMod/micropython$ make -C ports/rp2 submodules
make: Entering directory '/mnt/e/work/PythonMod/micropython/ports/rp2'
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
make -f ../../py/mkrules.mk GIT_SUBMODULES="lib/pico-sdk" submodules
make[1]: Entering directory '/mnt/e/work/PythonMod/micropython/ports/rp2'
  :
  :
Resolving deltas: 100% (918/918), done.
Submodule path 'lib/tinyusb': checked out '5217cee5de4cd555018da90f9f1bcc87fb1c1d3a'
make[1]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2'
make: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2'
```

#### ツールのビルド
```
/e/work/PythonMod/micropython$ make -C mpy-cross
make: Entering directory '/mnt/e/work/PythonMod/micropython/mpy-cross'
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
mkdir -p build/genhdr
GEN build/genhdr/mpversion.h
GEN build/genhdr/qstr.i.last
    :
CC ../shared/runtime/gchelper_generic.c
LINK build/mpy-cross
   text    data     bss     dec     hex filename
 400585   17792     864  419241   665a9 build/mpy-cross
make: Leaving directory '/mnt/e/work/PythonMod/micropython/mpy-cross'
/e/work/PythonMod/micropython$ 
```

#### MicroPythonのビルド

ports/rp2でmakeを実行し、本体をビルドする。

```
 $ make
```

BORDシンボルでビルドのターゲットを変更できる。省略時は、Raspberry Pi Pico無印（BOARD=RPI_PICO と同じ）。たとえば ```make BOARD=RPI_PICO2 ```  などとすれば、Raspberry Pi Pico 2としてビルドできる。

指定可能なビルドターゲットは、…\micropython\ports\rp2\boards　内にフォルダとして含まれている。
良く使うだろうと思われるものは次の通り。

|指定する引数|対象デバイス|
|:--- |:---:|
|BOARD=RPI_PICO|Raspberry Pi Pico(デフォルト）|
|BOARD=RPI_PICO_W|Raspberry Pi Pico W|
|BOARD=RPI_PICO2|Raspberry Pi Pico 2|
|BOARD=RPI_PICO2_W|Raspberry Pi Pico2 W|

今回の実行例では、PICOとして実行しているが、適宜引数を追加して環境にあわせる。

初回は、いくつか警告が出る。また、PicoToolがインストールされていないという警告が出て、自動的にダウンロードされるので時間がかかる。(２０分程度）

実行例
```
 $ cd ports/rp2
 $ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
[ -e build-RPI_PICO/Makefile ] || cmake -S . -B build-RPI_PICO -DPICO_BUILD_DOCS=0 -DMICROPY_BOARD=RPI_PICO -DMICROPY_BOA
   :
  (略）
   :
CMake Warning at /e/work/PythonMod/micropython/lib/pico-sdk/tools/Findpicotool.cmake:30 (message):
  No installed picotool with version 2.1.1 found - building from source
   :
  (略）
   :
[ 97%] Building C object CMakeFiles/firmware.dir/e/work/PythonMod/micropython/lib/tinyusb/src/class/vendor/vendor_device.c.o
[ 97%] Building C object CMakeFiles/firmware.dir/e/work/PythonMod/micropython/lib/tinyusb/src/class/video/video_device.c.o
[ 97%] Building C object CMakeFiles/firmware.dir/e/work/PythonMod/micropython/lib/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c.o
[ 97%] Building C object CMakeFiles/firmware.dir/e/work/PythonMod/micropython/lib/pico-sdk/src/rp2_common/cmsis/stub/CMSIS/Device/RP2040/Source/system_RP2040.c.o
[ 98%] Linking CXX executable firmware.elf
   text    data     bss     dec     hex filename
 332792       0    5484  338276   52964 /e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO/firmware.elf
make[3]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO'
[100%] Built target firmware
make[2]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO'
make[1]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO'
/e/work/PythonMod/micropython/ports/rp2$   
```

### ビルドされたものを確認する

ビルドは、ターゲット（今回は指定していないので、Raspberry Pi Pico ）の種類ごと、サブフォルダに```firmware.uf2```の名前で生成される。

内容を確認し、正しくビルドされたかを調査する。


```
/e/work/PythonMod/micropython/ports/rp2$ ls -al  build-RPI_PICO/firmware.uf2
-rwxrwxrwx 1 user user 665600 Mar 12 13:27 build-RPI_PICO/firmware.uf2
```

micropython/ports/rp2/build-RPI_PICO/_deps/picotool/には、picotoolというツールが同時に生成される。このツールを使って生成されたuf2の詳細を確認できる。

```
/e/work/PythonMod/micropython/ports/rp2$ build-RPI_PICO/_deps/picotool/picotool info -a build-RPI_PICO/firmware.uf2
File build-RPI_PICO/firmware.uf2 family ID 'rp2040':

Program Information
 name:              MicroPython
 version:           v1.25.0-preview.365.g3823aeb0f
 features:          thread support
                    USB REPL
 frozen modules:    neopixel, dht, ds18x20, onewire, uasyncio, asyncio/stream, asyncio/lock, asyncio/funcs,
                    asyncio/event, asyncio/core, asyncio, _boot_fat, _boot, rp2
 binary start:      0x10000000
 binary end:        0x100513f8
 embedded drive:    0x100a0000-0x10200000 (1408K): MicroPython

Fixed Pin Information
 none

Build Information
 sdk version:       2.1.1
 pico_board:        pico
 boot2_name:        boot2_w25q080
 build date:        Mar 12 2025
 build attributes:  MinSizeRel

Metadata Blocks
 none
```


## ILI9341のライブラリをMicroPythonに組み込む

### ライブラリのソースコードの入手

MicroPythonのビルドができるようになったので、次にILI9341のライブラリをユーザー定義Cモジュールとして組み込む。
[ILI9341のライブラリについて詳細はここを参照すること](https://qiita.com/BUBUBB/items/7c6777c04dedf01d7c3b)。

今回は、拡張ライブラリのソースコードは　```micropython/ports/rp2/myModule```　に配置してビルドすることにする。事前に、このフォルダを作成しておく。

```
/e/work/PythonMod/micropython/ports/rp2$ mkdir myModule
```

[GitHubのリリースページ](https://github.com/HisayukiNomura/KNJGfx9341/releases)から、Download codeをクリックし、zipファイルをダウンロードする。

Zipファイルから```lib-9341``` サブフォルダの内容を、```micropython\ports\rp2\myModule```にコピーしておく。
その後、次のフォルダについて、削除や移動する。

- ForMPY …　ファイルの内容をmyModule直下に移動する
- ForMPY/tasks.json.txt 名前をtasks.jsonに変更し、ルートディレクトリ/.vscodeに移動する
- Examples - 削除　(Ardiuno IDE用なので不要）
- library.properties - 削除　(Ardiuno IDE用なので不要）
- KNJGfx9341.h - 削除　(Ardiuno IDE用なので不要）

最終的に、次のようなファイル構成になる。

```
/
├─── .vscore
│　　　│
│　　　└───　.tasks.json ビルド用の設定ファイル
│
└──── micropython
 　　　│
 　　　├───　.git
 　　　├───　.github
 　　　├───　docs
 　　　├───　drivers
      ：　　　：
 　　　├───　ports
 　　　│     ├─── rp2      
 　　　│     ：   ├── boards
 　　　│     ：   :
 　　　│     ：   └── myModle
 　　　│     ：       ├── Adafruit_GFX_Library
 　　　│     ：       │    ├──
 　　　│     ：       │    :
 　　　│     ：       ├── Adafruit_ILI9341
 　　　│     ：       │    ├──
 　　　│     ：       │    :
 　　　│     ：       ├── core
 　　　│     ：       │    ├──
 　　　│     ：       │    :
 　　　│     ：       ├── Kanji
 　　　│     ：       │    ├── Fonts
 　　　│     ：       │    ├── KanjiHelper.cpp
 　　　│     ：       │    └── KanjiHelper.h
 　　　│     ：       ├── misc
 　　　│     ：       │    ├──
 　　　│     ：       │    :
 　　　│     ：       ├── spi
 　　　│     ：       │    ├──
 　　　│     ：       │    :
 　　　│     ：       ├── XPT2046_Touchscreen
 　　　│     ：       │    ├──
 　　　│     ：       │    :
 　　　│     ：       ├── gfx.cpp
 　　　│     ：       ├── GFXModule.c
 　　　│     ：       ├── GFXModule.h
 　　　│     ：       └── micropython.cmake
 　　　│     ├─── samd          
 　　　│     ├─── stm32          
 　　　│     └─── zephyr 
 　　　├───　py
      ：
 　　　└───　tools
 
```

### ビルドの実行

今回は、tasks.jsonにかかれた設定に基づいてビルドを行う。 Visual Studioのワークスペースフォルダ/.vscode/tasks.json　を前のステップでコピーしたが、それを利用する。
WSLから、code と入力するとVisual Studio Codeが起動する。

起動したら、Micropyton のソースコードが含まれているフォルダを開き、CTRL+SHIFT+dを押す。（もしくはコマンドパレットから「ビルドタスクの実行」を選択する）

次の順番でビルドを実行する。
1. SubmoduleのMake / ボード名
1. ToolのMake  / ボード名
1. MicropthonのMake / ボード名

<img width=60% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/a1ec38c3-70a1-4e6f-9712-2a5081bc4239.png">

ビルドが完了すると、
`<プロジェクトルート>\micropython\ports\rp2\build-RPI_PICO`
内に、firmware.uf2が生成される。


### フォントの変更

Micropythonで使用するフォントを変更する場合、`<プロジェクトルート>\micropython\ports\rp2\myModle\GFX.cpp` を変更する必要がある。

ソースコード中、フォントをインクルードしている部分を変更する。
```
#include "../Kanji/Fonts/JF-Dot-Shinonome16_16x16_LEVEL1.inc"
```
の部分で、使用したいフォントをincludeする。

次に、ソースコードの２２０行目付近、loadDefaultKanjiFont　メソッドの#defineを変更する。前の手順でincludeしたファイル内で定義されている構造体名を指定する。
```
	mp_obj_t loadDefaultKanjiFont(mp_obj_t a_Target)
	{
		if (!mp_obj_is_int(a_Target)) raise_mustInt();
		int iTarget = mp_obj_get_int(a_Target);

		msg_OnDebug("loadDefaultKanjiFont(%d)\r\n", iTarget);
#define KANJI_CODESET JFDotShinonome16_16x16_LEVEL1　　　　　←　この部分
#define KANJI_BITMAP JFDotShinonome16_16x16_LEVEL1_bitmap　　←　この部分
		if (iTarget == 0) { // ターゲットが０なら、TFT
			pTFT->setFont(KANJI_CODESET, KANJI_BITMAP);
		} else { // ターゲットが０以外なら、キャンバス
			canvasTable[iTarget - 1].setFont(KANJI_CODESET, KANJI_BITMAP);
		}
```

この二カ所を変更すしてビルドすると、Micropythonで使用しているフォントが変更できる。

---
# よくあるトラブル

## WSLで apt upgradeを実行するとエラーが発生する

sudo apt upgrade 中に、```Failed to take /etc/passwd lock: Invalid argument```というエラーが発生した場合、次のコマンドを実行し、問題が修正してから再実行する。　[こちらも参照](https://github.com/microsoft/WSL/issues/10397)

```
~$ cd /bin
/bin$ sudo mv -f systemd-sysusers{,.org}
/bin$ sudo ln -s echo systemd-sysusers
```



## 何もしていないのにビルドに失敗するようになってしまった

ビルドに失敗したり、何かの操作を途中で中断すると次回からmakeが動かなくなってしまうことがある。その場合は、次のフォルダの中にあるファイルを削除し、中途半端に生成されたファイルを削除すること。(イタリック部分-RPI_PICOなどは、ビルド時の引数指定により異なる。通常、複数あった場合にはすべて削除してよい。

- レベル１
E:\work\PythonMod\micropython\ports\rp2\\build-*RPI_PICO*\CMakeCache.txt
E:\work\PythonMod\micropython\ports\rp2\\build-*RPI_PICO*\generated　フォルダ

- レベル２
レベル１に加え、次のフォルダを削除する
E:\work\PythonMod\micropython\mpy-cross\build

- レベル３
E:\work\PythonMod\micropython\ports\rp2\\build-*RPI_PICO フォルダすべて

## ユーザーモジュールが組み込まれない

Raspberry Pi Pico上でサンプルプログラムを実行しても、KNJGfxモジュールのインポートができない場合には次のようなエラーが発生する。
```
ImportError: no module named 'KNJGfx'
```
この場合、makeコマンドで指定している引数
```USER_C_MODULES=/e/work/PythonMod/micropython/ports/rp2/myModule/micropython.cmake```
のファイルが存在するか、内容が正しいかを確認する。

問題がない場合、ビルドのログでユーザーモジュールが認識されているかを確認する。ビルドログの前半（３０秒頃）に、組み込まれたユーザーモジュールが表示されている。
```
    :
Including User C Module(s) from /e/work/PythonMod/micropython/ports/rp2/myModule/micropython.cmake
Found User C Module(s): KNJGfx
-- Configuring done (32.3s)
   :
```

- ```Found User C Module(s): KNJGfx``` としてKNJGfxが表示されている場合、モジュールは正常に組み込まれているので、ファームウェアのコピーが正しく行われているか、Python側のサンプルプログラムに誤りが無いかを確認する
- ```Found User C Module(s): ```　とだけ表示されている場合、モジュールは組み込まれていないので、makeの引数や、cmakeファイルを再度確認する
- この行自体が存在しない場合、ビルドフォルダ（build-*RPI_PICO）を削除して、再度完全にビルドする。

## MP_QSTR_XXXXでビルドエラーが発生する

GFXModule.cのMP_DEFINE_CONST_FUN_OBJ_nではエラーが発生せず、MP_QSTR_XXXXマクロでだけエラーが発生することがある。

例
```
GFXModule.c:67:22: error: 'MP_QSTR_InitHW' undeclared here (not in a function); did you mean 'MP_QSTR_init'?
```

この場合、コンパイル後のオブジェクト間でUSE_MICROPYTHON_MODULEのシンボルの整合性が取れていない可能性がある。この場合、```E:\work\PythonMod\micropython\ports\rp2\\build-*RPI_PICO``` フォルダすべてを削除し、完全なビルドを行う。 (make cleanはあてにならない・・・）

## ビルド時にcyw43-driver not initializedのエラーが発生する

ビルドの際に、次のようなエラーが発生することがある。

```
CMake Error at CMakeLists.txt:391 (message): cyw43-driver not initialized. Run 'make BOARD=RPI_PICO_W submodules'
```

この場合、submoduleのmakeと、本体のmakeでターゲットボードが異なっている。

一度、submoduleのビルドに戻り、git submodule update --initを実行してサブモジュールをリセットしてから、正しいBOARD引数（MicroPythonのビルドで使用したものと同じ引数）を使用して再ビルドを行う）


# 権利に関する表記
このライブラリは、Adafruitのグラフィックライブラリを改変して作成されました。
Adafruitのライブラリは、2条項BSDライセンスに基づきソースコードの再配布が許可されています。
Micropythonは、MITライセンスに基づきソースコードの再配布が許可されています。
（MITライセンスと二条項BSDライセンスは同じ）

これに基づいて、本ライブラリの権利も同じ2条項BSDライセンスに基づくものとします。