何が悪いのかは未だ判明しておりません。
以下では初期化に成功しておらず
*GPPUDCLK0 = (1 << 14) | (1 << 15);
delay(150);
以下で認識しました。
pinMode(14, INPUT_PULLDOWN);
pinMode(15, INPUT_PULLDOWN);
pinMode(14, ALT0);
pinMode(15, ALT0);
おそらく、ですがこの差分が核心なのかどうか。
その前に
ドキュメントを確認します。baremetal 本とかマニュアルなど。まず GPFSEL なレジスタなんですがそれぞれの GPIO に対して 3bit が確保されているとのこと。モードについてはマニュアルに以下な形で記載されてますね。
000 = GPIO Pin 39 is an input
001 = GPIO Pin 39 is an output
100 = GPIO Pin 39 takes alternate function 0
101 = GPIO Pin 39 takes alternate function 1
110 = GPIO Pin 39 takes alternate function 2
111 = GPIO Pin 39 takes alternate function 3
011 = GPIO Pin 39 takes alternate function 4
010 = GPIO Pin 39 takes alternate function 5
左のビットから見てって選り分けるのかな。4、5 なあたりが若干微妙なアレ。
以降に他のレジスタの記述あり。
- GPSET は GPIO の出力を High にする
- GPCLR は GPIO の出力を Low にする
これ、GPFSEL で output にしとかなきゃ駄目なんだろうな。逆に input にしてれば
- GPLEV は GPIO の入力で High なら 1 で Low なら 0
あと、肝心の GPPUD と GPPUDCLK についても記述あり。Pull Up とか Pull Down についての理解が微妙だったのですが、入力を High または Low に固定 とあります。
基本的には
- GPPUD に off/Pull Down/Pull Up のいずれかを設定
- GPPUDCLK で対応する GPIO を指定
という形になるのかな。
UART
マニュアル見てるのですが
- GPIO14 (8) を Pull が Low で ALT0 が TX
- GPIO15 (10) を Pull が Low で ALT0 が RX
らしい。あと PL011 という UART のマニュアル (日本語) が以下とのこと。
実装確認
諸々理解できたのかどうかは不明ですが実装確認してみます。成功した方の pinMode が実際どうなるか、というと
*GPPUD = 0x01;
delay(150);
*GPPUDCLK0 = (0x01 << 14)
delay(150);
*GPFSEL1 &= (~(vu32_t)(0x07 << ((14 % 10) * 3)))
*GPFSEL1 |= (0x04 << ((14 % 10) * 3))
*GPPUD = 0x01;
delay(150);
*GPPUDCLK0 = (0x01 << 15)
delay(150);
*GPFSEL1 &= (~(vu32_t)(0x07 << ((15 % 10) * 3)))
*GPFSEL1 |= (0x04 << ((15 % 10) * 3))
ってなるのかな。別途書き換えてみて確認してみます。それぞれ一体何をしてるのか、というと
- Pull Down Control を enable (*GPPUD = 0x01)
- wait 150 cycle
- GPPUDCLK の該当の番号に合致する部分のビットを立てて
- wait 150 cycle
- GPFSEL の該当の番号に合致する部分、0 で初期化
- GPFSEL の該当の番号に合致する部分のフラグを設定 (ALT0 なので 0x04)
ってことになるのか。これって GPIO 設定の一連の作法なのかな。
UART 初期化の全体について
つうか何故に動かんかったのか、というあたりが若干微妙。とりあえず初期化云々なあたりの記述を見つつレジスタの中身見てもごもごしてみる方向です。
初期処理全般については別途エントリおこす方向で。