キノコの自省録

日々適当クリエイト

RaspberryPi ZeroでGPIOを使って音声出力をするお話(2)

以下の続編(解説編)です。音声出力というより、どちらかというとGPIOのAlternative Functionの話です。

kinokorori.hatenablog.com

そもそも一体何をしているのか

dtoverlayを使用した方法では、以下のような指定をして、PWMを有効にしました。

dtoverlay=pwm-2chan,pin=18,func=2,pin2=13,func2=4

また、gpio_altを使用した方法では、最終的には、以下を実行して、PWMを有効にしました。

$ gpio_alt -p 13 -f 0
$ gpio_alt -p 18 -f 5

果たしてこれは何をしているのでしょう、というお話。

PWM(パルス幅変調)を用いて音声出力する機能が、RaspberryPiに備わっています。それを有効にしているだけといえばだけです。PWMにはPWM0とPWM1の2pinが必要で、それをgpio_altやdtoverlayを使って有効にしているというのが、解説先で紹介されている方法です。

上記例では、GPIO 13のファンクションを0(ALT0)、GPIO 18のファンクションを5(ALT5)にすることで、GPIO13をPWM1に、GPIO18をPWM0に設定しています。

ALTって何?

BCM2835(RaspberryPiのCPU)のGPIOピンには、切り替え可能な機能が最大6種類割り振られています。それがALT0やALT5と呼ばれるものです。raspi-configを使用して、I2CやSPIなどを有効にしたことがあると思いますが、それは、対応するピンをALT0に変更するということを裏で行っています。ALTを設定していない状態の場合、大抵はINです。IN、つまり外部からHIGH/LOWを受け取るだけの単純な機能ということです。

ALT0がどういう機能なのか、ALT5がどういう機能なのかは、このページを参照するのが良いと思います。

RPi BCM2835 GPIOs - eLinux.org

この表の通り、GPIO13のALT0はPWM1、GPIO18のALT5はPWM0です。GPIO18をALT0(I2S)として使いたい場合、別のPWM0の機能を持つピンを探せばよいということです。GPIO12のALT0にPWM0がありますので、gpio_altの場合、

$ gpio_alt -p 13 -f 0
$ gpio_alt -p 12 -f 0

を実行して、GPIO18からGPIO12に配線しなおせば、ちゃんと音声の再生ができるようになります。

dtoverlayの場合は、

dtoverlay=pwm-2chan,pin=12,func=4,pin2=13,func2=4

となります。func=4がALT0です。紛らわしいので注意。うまく再生できない場合はgpio readallで確認しましょう。