概要
ラズパイ入門キット「SunFounder Da Vinci Kit for Raspberry Pi」に入っている機器をRaspberr Pi Pico + Zephyr OSで動かしてみた。
今回は、RGB LEDを試した。
環境
Raspberr Pi PicoとLEDを以下のように接続する。接続方法はSunFounderのチュートリアルを参考にした。
使用したソフトはZephyr OSの以下のサンプルコードで、デバイスツリーのみ上記の回路に合わせて変更した。
https://github.com/zephyrproject-rtos/zephyr/blob/main/samples/basic/rgb_led/src/main.c
使用方法
作成したソースコードを以下に格納したので、これを使用する。
GitHub - aimdevel/my-zephyr-applications
Zephyrの開発環境構築については公式ドキュメントを参照。
Getting Started Guide — Zephyr Project Documentation
環境をセットアップ
west init -m https://github.com/aimdevel/my-zephyr-applications.git --mr main my-workspace cd my-workspace/ west update
この手順はこのリポジトリを利用するときに1回だけ実施すればよい。
ビルド
west build -b rpi_pico apps/apps/rgb_led/
基板に焼いて動作確認
時間経過でLEDの色が変化する様子を確認できる。
ソースコード説明
devicetree
devicetreeは以下。
https://github.com/aimdevel/my-zephyr-applications/blob/main/apps/rgb_led/boards/rpi_pico.overlay
全体は以下のようになっている。
/{ aliases { red-pwm-led = &red_pwm_led; green-pwm-led = &green_pwm_led; blue-pwm-led = &blue_pwm_led; }; pwmleds { compatible = "pwm-leds"; red_pwm_led: red_pwm_led { pwms = <&pwm 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>; }; green_pwm_led: green_pwm_led { pwms = <&pwm 3 PWM_MSEC(20) PWM_POLARITY_NORMAL>; }; blue_pwm_led: blue_pwm_led { pwms = <&pwm 4 PWM_MSEC(20) PWM_POLARITY_NORMAL>; }; }; }; &pwm { status = "okay"; divider-frac-1 = <15>; divider-int-1 = <255>; divider-frac-2 = <15>; divider-int-2 = <255>; }; &pwm_ch4b_default { group2 { pinmux = <PWM_1A_P2>, <PWM_1B_P3>, <PWM_2A_P4>; }; };
aliases
各ノードに別名をつける設定。
アプリのコードからデバイスツリーにアクセスする際に使用できる。
ここでは、各色に対応するノードに設定を行っている。
aliases { red-pwm-led = &red_pwm_led; green-pwm-led = &green_pwm_led; blue-pwm-led = &blue_pwm_led; };
pwmleds
それぞれの色にPWMを割り当てている。
1つだけ取り出して見る。
red_pwm_led: red_pwm_led { pwms = <&pwm 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>; };
これは赤色をpwmの2番(GPIO2のピン)で制御することを表している。ほかの色も同様である。
細かい設定は公式ドキュメントを参照。
Pulse Width Modulation (PWM) — Zephyr Project Documentation
pwm
pwmの設定。
&pwm { status = "okay"; divider-frac-1 = <15>; divider-int-1 = <255>; divider-frac-2 = <15>; divider-int-2 = <255>; };
status = "okay";
でpwmを有効にしている。
そのほかは分周の設定で、Zephyr OS公式を参考に設定した。
pwm_ch4b_default
ピンの設定。
名前はch4bだが、それ以外のチャネルもここで設定できる。
&pwm_ch4b_default { group2 { pinmux = <PWM_1A_P2>, <PWM_1B_P3>, <PWM_2A_P4>; }; };
この1Aなどの値がPWMのチャネルなのだが、この値とGPIOの関係はデータシートによると以下のようになっている。
今回はGPIO2, 3, 4をPWMとして使用するので、対応するpwmのチャネルは1A, 1B, 2Aとなっており、上記のピン設定となる。
サンプルコード
公式のサンプルコードから全く手を加えていない。
pwmを制御する際に行っているのは以下の部分。
- デバイスツリーから情報を取得。
static const struct pwm_dt_spec red_pwm_led = PWM_DT_SPEC_GET(DT_ALIAS(red_pwm_led)); static const struct pwm_dt_spec green_pwm_led = PWM_DT_SPEC_GET(DT_ALIAS(green_pwm_led)); static const struct pwm_dt_spec blue_pwm_led = PWM_DT_SPEC_GET(DT_ALIAS(blue_pwm_led));
DT_ALIASでaliasesで設定した名前を使用できるはずだが、ここではアンダースコア表記。
- pwmの値を設定
ret = pwm_set_pulse_dt(&red_pwm_led, pulse_red);
pwm_set_pulse_dt関数にデバイスの構造体とパルスの値を渡して制御する。
まとめ
デバイスツリーの対応だけでサンプルコードを動かせることを確認した。
pwmの制御だけなので、前回のサーボモータを動かすサンプルとほぼ同じ内容だった。
ラズパイ入門キットには、ほかにも多くのデバイスが含まれているのでそれらの動作にも挑戦していく。
参考
1.1.2 RGB LED — SunFounder davinci-kit-for-raspberry-pi ドキュメント