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

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

[Rapberry PI Pico用　ST7735 TFT液晶 SDKライブラリ](https://qiita.com/BUBUBB/items/3caf2aefba4ae3a715e1) でC/C++(公式SDK)での使用例を公開したが、そのままでは　MicroPythonから呼びだすことはできない。

MicroPythonでは、外部Cモジュールとして、C言語で書かれたプログラムをMicroPythonに取り込んでビルドすることで、MicroPythonに機能を追加することができる。この機能は、メインの MicroPython リポジトリ外での実装となるため、既存のMicroPythonの機能を損なわず、また、MicroPythonのバージョンアップに対しても比較的安全になる。


この外部Cモジュールを使って、[Rapberry PI Pico用　ST7735 TFT液晶 SDKライブラリ](https://qiita.com/BUBUBB/items/3caf2aefba4ae3a715e1)を含んだMicroPythonをビルドした。

また、ビルド済みのイメージを提供してあるので、SDKのビルド環境が無い場合もMicroPythonのファームウェアをダウンロードして使用できる。


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

```
import KNJGfx

BLACK = 0x0000
WHITE = 0xFFFF

spi = machine.SPI(0,baudrate=10000000, polarity=0,phase=0,sck=machine.Pin(18),mosi=machine.Pin(19),miso=machine.Pin(16))
KNJGfx.InitHW((0,16, 17, 18, 19, 28, 15))
KNJGfx.CreateGFX(1)
KNJGfx.doInit()
KNJGfx.drawTextKanji((0,15,WHITE,BLACK,False),"こんにちは！")
```
<img width=40% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/f91c2952-cbbd-4649-8a19-326eb15744f7.png">

# とにかく使ってみたい人

とにかくまずは使ってみたい、という場合は、[ビルド済みのイメージを使用する](#ビルド済みのイメージを使用する)まで読み飛ばす。

[ビルド済みのイメージを使用する](#ビルド済みのイメージを使用する)以降では、SDKやC言語ではなく、ダウンロードしたイメージを使用し、Pythonプログラムから液晶に画像を表示する部分を説明してある。

<iframe height="480" src="https://www.youtube.com/embed/J6AZSSsFmCU" title="Japanese text on ST7735 #micropython #raspberrypipico #電子工作" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


# 外部Cモジュールが組み込まれたMicroPythonをビルドする

ここでは、Windows10/11とRaspBerryPi、インターネット環境だけを持っている人が、ST7735の機能を含んだMicroPythonをビルドするための手順を解説する。

※ ページの末尾に、[よくあるトラブル](#よくあるトラブル)が示されている。何かあったら参照すること。

実際に、ライブラリを組み込んだMicroPythonを使うための手順について、大きく分けて次のようなステップで説明する。一部、冗長な部分があるがビルドスクリプトが複雑で、何かあった時に少しずつ解決する必要があるので、この方法が良いと思われる

1. 環境の準備
1. MicroPythonのソースコードを取得してビルド。（この部分は冗長で、作成したものは使用しない。単にビルドできることを確認するだけになる。）
1. ST7735ライブラリを取得してMicroPythonの外部Cモジュールに登録、ビルド。実際にはこのステップで作成たものが使用される）
1. 実機でのテスト

手順は長いが、さほど複雑ではない。

操作では実際のコマンド例がそのまま書かれており、出力の一部も書いてある。時間がかかる操作には、おおよその時間（光回線と、中くらいの性能を持ったPCでの参考）が書いてある。一部、特に初回は時間がかかる作業があるので、焦らず待っていること。

# 環境の準備

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

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

そのため、エディタやファイルの管理などではWindowsを使用して、ビルドはWSLのubuntu を使用する方法で環境を作成する。

# WSLのインストール

WSLをインストールし、WSL1.0にバージョンダウンする。すでにWSLを使用している場合でも1.0に戻す必要がある。（1.0に戻しても既存の2.0環境は破壊されない。2.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
```

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

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

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

|名称|正式名称|概要|
|:--- |:---|:---|
|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
```


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


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

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

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

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

<img width=60% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/cbb954d0-c088-4310-9d2b-fb5174098c44.png">


Zipファイルの中から、ST7735-TFTDriver-X.X\lib-st7735\フォルダにある、includeフォルダと、srcフォルダを、フォルダごと/e/work/PythonMod/micropython/ports/rp2/myModuleにコピーしておく。
ファイルの構成は次のようになる。

```
/e/work/PythonMod/micropython/ports/rp2$ ls -R  myModule
myModule:
include  src

myModule/include:
GFXModule.h  KanjiHelper.h  ST7735_TFT.h  ST7735_commands.h  ST7735_initcmd.h  ST7735_struct.h  TextFonts.h  font  hw.h

myModule/include/font:
Font_Kanji12All.inc     Font_Kanji16All.inc     Font_Kanji8All.inc     Font_Mono18p.h
Font_Kanji12Jyoyo.inc   Font_Kanji16Jyoyo.inc   Font_Kanji8Jyoyo.inc   Font_Mono9p.h
Font_Kanji12Kyoiku.inc  Font_Kanji16Kyoiku.inc  Font_Kanji8Kyoiku.inc  FreeMonoOblique12pt7b.h
Font_Kanji12Level1.inc  Font_Kanji16Level1.inc  Font_Kanji8Level1.inc  FreeMonoOblique12pt_sub.h

myModule/src:
GFX.cpp  GFXModule.c  KanjiHelper.cpp  ST7735_TFT.cpp  ST7735_initcmd.cpp  hw.cpp
user@machine:/e/work/PythonMod/micropython/ports/rp2$
```

それぞれのファイルやディレクトリの意味は、[Rapberry PI Pico用　ST7735 TFT液晶 SDKライブラリ](https://qiita.com/BUBUBB/items/3caf2aefba4ae3a715e1)を参照。

また、zipファイルの　documents\htmlには、ライブラリの詳細なドキュメントが含まれている。このフォルダを解凍し、index.htmlを表示させると、ドキュメントが参照できる。それぞれのファイルについて解説されているので必要なら参照すること。

### MicroPython関連機能の有効化

デフォルトでは、このソースコードはMicroPython関連の機能は無効になっている。
includeフォルダに移動し、GFXModule.hをエディタで開く

.../myModul$ cd myModule/include/
.../myModule/include$ nano GFXModule.h

ファイルの５行目にある、```// #define USE_MICROPYTHON_MODULE```　行のコメントを外す。

<img width=80% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/f933bca7-f9d9-4d1c-8f9a-42f541aedd9f.png">


### cmakeファイルを作成する

myModuleのディレクトリに、micropython.cmakeという名前で、cmakeファイルを作成する。
MicroPythonのビルドについては、対象のハードウェアごとに流れが違ってくる。

Raspberry Pi Picoの場合、makeファイルの引数として、cmakeファイルを渡し、makeがcmakeを起動するという流れになる。その、makeに渡すためのファイルで、ライブラリのソースコードがコンパイルに含まれるようにし、さらにMicroPythonがライブラリを呼びだせるようにするためのインタフェースを定義する。

※ このファイルは自分で作らずgithubから持ってきたzipに含まれるものを使っても良い。

```
# Micropythonの拡張Cモジュールとしてビルドするときに使用する cmakeファイル。
# C/C++から使用するときにはこのcmakeファイルは使われない。

# インタフェースライブラリを作成する。
add_library(KNJGfx INTERFACE)

# ビルド対象となるファイルをここに指定する
target_sources(KNJGfx INTERFACE
    ${CMAKE_CURRENT_LIST_DIR}/src/GFX.cpp
    ${CMAKE_CURRENT_LIST_DIR}/src/GFXModule.c
    ${CMAKE_CURRENT_LIST_DIR}/src/ST7735_TFT.cpp
    ${CMAKE_CURRENT_LIST_DIR}/src/ST7735_initcmd.cpp
    ${CMAKE_CURRENT_LIST_DIR}/src/KanjiHelper.cpp
    ${CMAKE_CURRENT_LIST_DIR}/src/hw.cpp
 )

# インクルードディレクトリをカレントディレクトリに設定。
# ソースコードからのインクルードでは ../include/XXXX.h としてインクルードするのでここは
# このままでいい
target_include_directories(KNJGfx INTERFACE
    ${CMAKE_CURRENT_LIST_DIR}
)

# ユーザーモジュールライブラリとしてリンクする
target_link_libraries(usermod INTERFACE KNJGfx)
```

### 機能のカスタマイズ

もし、使用するフォントを変更したり、不要な機能を削除してメモリを節約したいなどがあれば、KanjiHelper.h（フォントの種類や数）や、ST7735_TFT.h（描画機能の削除）を編集する。[実際の編集方法はここ](https://qiita.com/BUBUBB/items/3caf2aefba4ae3a715e1#%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E3%83%8B%E3%83%BC%E3%82%BA%E3%81%AB%E5%90%88%E3%82%8F%E3%81%9B%E3%81%A6%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B%E3%82%82%E3%81%AE)を参照。

たとえば、漢字のフォントを16x16ドット、常用漢字のみにしたい場合、KanjiHelper.h　を次のように変更する。

```
#define TFT_KANJI_DOT 16
#define TFT_KANJI_LEVEL 2
```


### ビルド

準備が整ったら、ports/rp2フォルダでビルドコマンドを発行する。（２０分）
```
$ make  USER_C_MODULES=/e/work/PythonMod/micropython/ports/rp2/myModule/micropython.cmake
```
このとき、USER_C_MODULESとして、前のステップで作成したcmakeファイルを指定する。ビルドの途中（３０秒程度）で、読み込まれた cmakeファイルと、組み込まれるユーザーモジュールが表示される。

実行例
```
$ cd /e/work/PythonMod/micropython/ports/rp2
$ make  USER_C_MODULES=/e/work/PythonMod/micropython/ports/rp2/myModule/micropython.cmake 
 　　　：
     （略）
 　　　：
  PICO_LWIP_PATH specified but content not present.
Including User C Module(s) from /e/work/PythonMod/micropython/ports/rp2/myModule/micropython.cmake
Found User C Module(s): KNJGfx
 　　　：
     （略）
 　　　：
[100%] Built target firmware
make[2]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO2'
make[1]: Leaving directory '/mnt/e/work/PythonMod/micropython/ports/rp2/build-RPI_PICO2'
/e/work/PythonMod/micropython/ports/rp2$
```

この例では、Raspberry Pi Pico 無印でビルドしている。ターゲットのボードがPICO2の場合などは、適宜```BOARD=RPI_PICO2```などを追加する。[詳細はMicroPythonのビルドを参照](#ビルド)。


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

自分でビルドせずビルド済みのイメージを使用したい場合や、Raspberry PI SDKの環境を持っていない場合、ビルド済みの拡張機能を含めたMicroPythonのファームウェア(firmware.uf2)をダウンロードできる。使い方は公式で配布されているものと同じ。

※ ページの末尾に、[よくあるトラブル](#よくあるトラブル)が示されている。何かあったら参照すること。

[githubのリリースページ](https://github.com/HisayukiNomura/ST7735-TFTDriver/releases)から、[ビルド済みバイナリ](https://github.com/HisayukiNomura/ST7735-TFTDriver/releases/download/0.9/ST7735Lib_binary.zip)をダウンロードし、必要なMicroPythonのファームウェアを入手する。



|フォルダ||含まれているフォント|
|:---- |:---:|:----|
|ST7735Lib_binary\Pythons\8x8_ALL\ | |8x8ドット、すべてのJIS文字|
|ST7735Lib_binary\Pythons\8x8_LV1\ | |8x8ドット、JIS第二水準を除くJIS文字|
|ST7735Lib_binary\Pythons\12x12_ALL\ | |12x12ドット、すべてのJIS文字|
|ST7735Lib_binary\Pythons\12x12_LV1\ | |12x12ドット、JIS第二水準を除くJIS文字|

それぞれのフォルダ内には、対象のハードウェアごとのサブフォルダが存在する。
|フォルダ||対象ハードウェア|
|:---- |:---:|:----|
|PICO1||Raspberry Pi Pico（無印）|
|PICO1W||Raspberry Pi Pico W（無印）|
|PICO2||Raspberry Pi Pico 2|
|PICO2W||Raspberry Pi Pico 2 W|

たとえば、12x12ドット、JISの第二水準文字は不要で、Raspberry Pi Pico W　で動作させるときには、
```ST7735Lib_binary\Pythons\12x12_LV1\PICO1W\firmware.uf2```
を使用することになる。

手持ちのデバイスの関係上PICO2しかテストしていない。



# ファームウェアのコピーとテスト

## TFT液晶とRaspberry Pi Picoの接続

接続する液晶のドキュメントなどを参照し、Raspberry Pi Picoと液晶を接続する。TFT液晶側の端子名の表記や呼び方は製品により異なるので、それぞれの製品にあわせて確認が必要。
下の表は、呼び方やドキュメント上の表記、シルク印刷の表記例を示す。カッコ内は[aitendoの1.8インチTFT液晶モジュール M018C7735S541](https://www.aitendo.com/product/16367)での表記だが微妙に間違えている気がするので、カッコつきで表記した。基本的に、CSn/SCKについては迷うことは無いと思うが、MISOとMOSIについては液晶側の表記はかなりばらつきがある。（誰か統一してくれ・・・）

|Raspberry PI|⇔|TFT液晶|
|:---- |:---:|:----|
|GP16(21Pin)・MISO、SDI、RX、D/C||SDO、DC、(RS)|
|GP17(22Pin)・CSn||CS、CSn、CSB|
|GP18(23Pin)・SCK||SCK、SCL|
|GP19(25Pin)・MOSI、SDO、TX||SDI、RX、(SDA)|

これらのポートは変更可能だが、変更した場合後述のPythonプログラム内でポート番号などを変更する必要がある。


[Rapberry PI Pico用　ST7735 TFT液晶 SDKライブラリ](https://qiita.com/BUBUBB/items/3caf2aefba4ae3a715e1#%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2) では、[aitendoの1.8インチTFT液晶モジュール M018C7735S541](https://www.aitendo.com/product/16367)での結線例を示してある。

<img width=60% alt="RaspTFT.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/8918b453-7dc3-4e5e-9b7b-5a1461ea670a.png">


## ファームウェアのコピー
Raspberry Pi Picoのボタンを押しながら、USBケーブルをPCに差し込む。PCで、Raspberry Pi Picoがドライブとして認識されるので、Windowsから/build-RPI_PICO2に作成されるfirmware.uf2をコピーする。

```
e:\work\PythonMod\micropython\ports\rp2>copy build-RPI_PICO2\firmware.uf2 d:\
```

コピーが終わると、自動的にUSBドライブが切り離される。これで、Raspberry Pi Picoに、外部Cモジュールが付加されたMicroPythonが動作するようになる。

## Pythonの開発環境を用意

### ダウンロード

多くの書籍などで推奨の開発環境として、[Thonny](https://thonny.org/) を使用するものとする。

Thonny の公式ページ　https://thonny.org/ に行き、右上のリンクからインストール先の環境を選び、ダウンロード、インストール。
インストールはすべてデフォルトで構わない。

<img width=80% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/86de5551-c33a-41e4-8182-f7dee6ce19e5.png">
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/3ca7abab-b23c-44f2-b31c-2e905ffabbec.png)

### Raspberry Pi Pico用に設定

インストールが終わったら、スタートメニューからthonny を起動し、メニューから[ツール]＞[オブション]を選択する。
<img width=60% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/7eec4687-1938-49bb-9941-1e90040c3d2e.png">

オプションダイアログが表示されるので、[インタプリタ]タブをクリック、ドロップダウンから [MicroPython（Raspberry Pi Pico）]を選択、OKを押してダイアログを閉じる。

<img width=60% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/9e646686-6030-4ae7-b6ce-a635ecac74a4.png">


### 動作の確認

[無題]などと書かれているタブに、次のようなコードを入力する。

```
import KNJGfx

BLACK = 0x0000
WHITE = 0xFFFF

spi = machine.SPI(0,baudrate=10000000, polarity=0,phase=0,sck=machine.Pin(18),mosi=machine.Pin(19),miso=machine.Pin(16))
KNJGfx.InitHW((0,16, 17, 18, 19, 28, 15))
KNJGfx.CreateGFX(1)
KNJGfx.doInit()
KNJGfx.fillScreen(BLACK)
KNJGfx.drawTextKanji((0,15,WHITE,BLACK,False),"こんにちは！")
```
入力が終わったら、ツールバーにある緑色の再生ボタンを押して、プログラムを実行する。再生ボタンがグレーになっている場合、[STOP]ボタンを押すと再生ボタンが押せるようになる。

<img width=80% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/7c2287cf-7a6b-4c26-a7de-fc6d19ccdfcb.png">

Raspberry Pi Picoに接続された液晶に、こんにちは！と表示される。
<img width=40% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/f91c2952-cbbd-4649-8a19-326eb15744f7.png">


# より複雑なプログラム

実際のライブラリの機能をより多く使うためのテスト用プログラムを用意してある。

1. テストプログラムのダウンロード
GitHubの[ST7735-TFTDriver＞MicroPythonExampleのページ](https://github.com/HisayukiNomura/ST7735-TFTDriver/tree/main/MicroPythonExample)から、userMod.py　と　bmpdata.py　をダウンロードする。userMod.pyは、テスト用プログラム本体、bmpdata.pyはビットマップデータ。<br/>

1. Raspberry Pi Picoの接続
ファームウェアを書き込み済みのRaspberry Pi Picoを、ボタンは押さずにそのままUSBポートに接続する。<br/>

1. テストプログラムの読み込み
Thonnyを起動し[ファイルを開く]>[このコンピュータ]を選択、ダウンロードした２つのファイルを読み込む。
<img width=80% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/60ee80d4-6d59-49c0-909f-31d8dfdc1166.png"><br/>
読み込みが完了すると、画面には読み込まれたプログラムが表示される。<br/>
<img width=80% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/edddda77-3fea-4b0d-a0c1-4f6954fda2a6.png"><br/><br/>

1. Raspberry Pi Picoへの転送
bmpdata.pyは、ビットマップデータを保存してあるファイルなので、実行されるプログラムとは別に、事前にRaspberry Pi Picoに転送しておく。
タブでbmpdata.pyを選択し、[ファイル]＞[名前を付けて保存]を選択、保存先にRaspberry Pi Picoを選択する。<br/>
<img width=80% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/3b351ed2-154c-4efa-b2aa-726ce13a8847.png"><br/>
保存先のダイアログでは、名前に```bmpdata.py```と入力し、OKを押して保存する。<br/>
<img width=80% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/0d8be181-89f9-48a8-98fa-b9009c7d1049.png"><br/>
保存にはしばらく時間がかかる。
<img width=50% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/cd45e6e9-b997-4a47-8027-8219f60bbc5a.png"><br/>
保存時に、```Device is busy```というエラーが出た場合、Raspberry Pi Picoが何かのプログラムを実行中の可能性がある。<br/>
<img width=50% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/e4772607-5121-41ed-96e9-260e7f5d7b2f.png">　<br/>
この場合、ツールバーのストップボタンを押して、Raspberry Pi Picoの動作を停止してから再実行する。<br/><img width=80% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/afb53779-e653-4dfa-a7f5-c0baf5fe4cbf.png"><br/>
1. テストプログラムの実行
ツールバーの再生ボタン、もしくはF5キーを押して、プログラムを実行する。<br/><img width=80% alt="ubuntu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/78028070-5197-4079-9538-08f86bd3871b.png"><br/>

1. テストプログラムについて
テストプログラムは、次の順番で実行される。<br/>
テキスト表示：フォント指定文字表示と縦スクロール⇒日本語表示と縦スクロール⇒画面回転の日本語表示とスクロール
ビットマップ表示：透過色指定なしのビットマップ表示⇒透過色指定つきのビットマップ表示⇒アニメーション例
基本描画機能：縦線⇒横線⇒点描画⇒画面反転
図形描画機能：矩形と塗りつぶし⇒直線描画⇒円と円塗りつぶし⇒角丸矩形と塗りつぶし

<iframe height="480" src="https://www.youtube.com/embed/J6AZSSsFmCU" title="Japanese text on ST7735 #micropython #raspberrypipico #電子工作" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>



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

## 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ライセンスに基づくものとします。