ラズパイPico用TOPPERS/ASPを133MHzで動かす

##はじめに
インターフェース誌 2021年８月号で**Raspberry Pi Pico**（以後、**ラズパイPico**）へTOPPERSを移植した記事を執筆しましたが、ラズパイPicoの動作クロックは**Pico-SDK**で提供されている以下のファイルの**clocks_init()**関数をそのまま利用し、**125MHz**で動作させていました。

```
pico-sdk/src/rp2_common/hardware_clocks/clocks.c
　clocks_init()
```

ただし、ラズパイPico搭載されているMCUの**RP2040**の仕様では、最大クロックは**133MHz**となっていてより高速に動作させることが可能そうなことが分かりました。
![TopClk_pic01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370759/eb8c88d3-bb63-9e12-92a8-f685b63f2c87.jpeg)
以前に以下のQiitaの記事で**FreeRTOS**を**133MHz**で動作させる方法を執筆しましたが、今回はラズパイPico用のTOPPERS/ASPの動作クロックを**133MHz**へ変更する方法を紹介したいと思います。

・ラズパイPicoの動作クロック変更
　https://qiita.com/Yukiya_Ishioka/items/66ac841959d17fb868f7


##変更方法
ラズパイPico用のTOPPERS/ASPの動作クロックを変更する手順は以下の２つになります。
**１）** Pico-SDKのクロック初期化の変更
**２）** TOPPERS/ASPのシステムクロック設定の変更

###１）Pico-SDKのクロック初期化の変更
Pico-SDKのクロック初期化は以下のファイル内の**clock_init()**関数で行われています。

```
pico-sdk/src/rp2_common/hardware_clocks/clocks.c
　clocks_init()
```

Interface誌８月号でTOPPERS/ASPの記事を執筆した際に使用したソースでは以下の**156**行目で
**125MHz**設定になるよう（**1500MHZ / 6 / 2 = 125MHz**）パラメータを設定して**pll_init()**関数を呼び出していました。

``` pico-sdk/src/rp2_common/hardware_clocks/clocks.c
145     /// \tag::pll_settings[]
146     // Configure PLLs
147     //                   REF     FBDIV VCO            POSTDIV
148     // PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz
149     // PLL USB: 12 / 1 = 12MHz * 40  = 480 MHz / 5 / 2 =  48MHz
150     /// \end::pll_settings[]
151
152     reset_block(RESETS_RESET_PLL_SYS_BITS | RESETS_RESET_PLL_USB_BITS);
153     unreset_block_wait(RESETS_RESET_PLL_SYS_BITS | RESETS_RESET_PLL_USB_BITS);
154
155     /// \tag::pll_init[]
156     pll_init(pll_sys, 1, 1500 * MHZ, 6, 2);　　← ココ
157     pll_init(pll_usb, 1, 480 * MHZ, 5, 2);
158     /// \end::pll_init[]
```

ラズパイPicoを**133MHz**で動作させるにはこの行の**pll_init()**関数へ渡す引数を以下のように変更します。

```
133 * 6 * 2 = 1596
```

```
    pll_init(pll_sys, 1, 1596 * MHZ, 6, 2);
```

ここでシステムクロックが **125MHz**から**133HMz**へ変更されるため、**125MHz**を期待して作られている処理の変更も必要になります。
修正が必要になるのは、同じく**clocks_init()**関数内の以下の２か所の**clock_configure()**関数の呼び出し部分になります。


・システムのクロック値の設定

``` pico-sdk/src/rp2_common/hardware_clocks/clocks.c
169     // CLK SYS = PLL SYS (125MHz) / 1 = 125MHz
170     clock_configure(clk_sys,
171                     CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
172                     CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
173                     125 * MHZ,
174                     125 * MHZ);
```

・ペリフェラルのクロック値の設定

``` pico-sdk/src/rp2_common/hardware_clocks/clocks.c
198     // CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select and enable
199     // Normally choose clk_sys or clk_usb
200     clock_configure(clk_peri,
201                     0,
202                     CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
203                     125 * MHZ,
204                     125 * MHZ);
```

この clock_configure()関数の引数のうち「**125 * MHZ**」と指定している部分を「**133 * MHZ**」へ変更します。
変更後は以下のようなります。

``` pico-sdk/src/rp2_common/hardware_clocks/clocks.c
169     // CLK SYS = PLL SYS (133MHz) / 1 = 133MHz
170     clock_configure(clk_sys,
171                     CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
172                     CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
173                     133 * MHZ,
174                     133 * MHZ);
```

``` pico-sdk/src/rp2_common/hardware_clocks/clocks.c
198     // CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select and enable
199     // Normally choose clk_sys or clk_usb
200     clock_configure(clk_peri,
201                     0,
202                     CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
203                     133 * MHZ,
204                     133 * MHZ);
```

Pico-SDK内の変更は以上になります。

###２）TOPPERS/ASPのシステムクロック設定の変更
ラズパイPico用TOPPERS/ASPではシステムクロックを使った**Cortex-M0+**に組み込まれているSystickタイマを使ってRTOSの動作に必要なタイマ割り込みを発生させています。

このため、MCUのシステムクロックが変更されると、その動作クロックに合わせて**TOPPERS/ASP**内のタイマ設定の変更が必要になります。

ラズパイPico用TOPPERS/ASPでは、**asp/target/pico_gcc/target_inithook.c**内の**sysclock_init_value()**関数、**sysclock_change()**関数のパラメータの変更を行うことになります。

``` asp/target/pico_gcc/target_inithook.c
 58 uint32_t
 59 sysclock_init_value(void)
 60 {
 61         return 125000000;       /* 125 MHz */
 62 }
 63
 64
 65 int
 66 sysclock_change(uint8_t range)
 67 {
 68         pico_clock_init();
 69         SystemFrequency = 125000000;
 70         return  0;
 71 }
```

それぞれの関数内の「**125000000**」と定義している部分が125MHz動作時のパラメータです。
システムクロックが**133MHz**へ変更された場合、この部分を「**133000000**」へ変更することになります。
変更後のソースは以下のようになります。

``` asp/target/pico_gcc/target_inithook.c
 58 uint32_t
 59 sysclock_init_value(void)
 60 {
 61         return 133000000;       /* 133 MHz */
 62 }
 63
 64
 65 int
 66 sysclock_change(uint8_t range)
 67 {
 68         pico_clock_init();
 69         SystemFrequency = 133000000;
 70         return  0;
 71 }
```

##ラズパイPico用TOPPERS/ASPのソースコードの入手について

ラズパイPico用TOPPERS/ASPのソースコードの入手やビルド方法はインターフェース誌 2021年８月号の「ITRON仕様OS TOPPERS/ASPの載せ方」を参照ください。

・インターフェース誌 2021年８月号
　https://interface.cqpub.co.jp/magazine/202108/
　ITRON仕様OS TOPPERS/ASPの載せ方
　https://interface.cqpub.co.jp/wp-content/uploads/if2108_109.pdf

各ソースのダウンロード先を以下に記しておきます。

・TOPPERS/ASPターゲット非依存部
　https://www.toppers.jp/download.cgi/asp-1.9.3.tar.gz

・TOPPERS新世代カーネル用コンフィギュレータ
　https://www.toppers.jp/download.cgi/cfg-1.9.6.tar.gz

・ラズパイPico用TOPPERS/ASP個別ソース
　https://www.cqpub.co.jp/interface/download/2021/08/IF2108TOPP.zip

・ラズパイPico-SDK
　https://github.com/raspberrypi/pico-sdk.gi
　（git clone -b master https://github.com/raspberrypi/pico-sdk.git）

##さいごに
**125MHz**から**133MHz**とわずかな違いですが、変更は容易だと思うので、一度、試してみてはどうでしょうか。
ただし、ネット上に公開されているラズパイPico用のプログラムなどは Pico-SDKデフォルトの設定での利用を想定していると思うので、自身の開発環境上に展開したPico-SDKを使いまわす場合には注意してください。

また、記事を執筆した2021年09月30日時点のラズパイPico-SDKのクロック設定を確認しましたが、以下のように125MHz設定は変わっていないようなので上記と同様の手順でクロック設定を変更できると思います。

``` pico-sdk/src/rp2_common/hardware_clocks/clocks.c
148     /// \tag::pll_settings[]
149     // Configure PLLs
150     //                   REF     FBDIV VCO            POSTDIV
151     // PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz
152     // PLL USB: 12 / 1 = 12MHz * 40  = 480 MHz / 5 / 2 =  48MHz
153     /// \end::pll_settings[]
154
155     /// \tag::pll_init[]
156     pll_init(pll_sys, 1, 1500 * MHZ, 6, 2);
157     pll_init(pll_usb, 1, 480 * MHZ, 5, 2);
158     /// \end::pll_init[]
```

－ 以上 －