2016/12/24

Raspberry Pi 3 Model B+ でベアメタル UART 出力

前回に引き続き、今回も下記サイトを参考にベアメタルプログラミングをしていく。

今回は UART でのデータ送受信。

参考ページは下記。

必要なハードウェアの調達

UART するには通信ケーブルが必要なので調達した。

ドライバは下記ページを参考にした。

UART を使用するための設定

config.txt を作成し、 enable_uart=1 を記述。 あとで SD カードのルートに格納する。

この辺は今のところ「おまじない」としておく。

このおまじないをすると、 GPU が Mini UART を使えるようにしてくれるようになるらしい。 そのため、我々は、 UART の初期化コードを書くことなくプログラミングできるっぽい。

UART を使うためのレジスタの確認

使うレジスタ

BCM-ARM-Peripherals.pdf の 8 ページ目から UART のレジスタについて説明されている。

今回使うのは、 AUX_MU_LSR_REG(Mini Uart Line Status)AUX_MU_IO_REG(Mini Uart I/O Data)

Raspberry Pi 3 なので、上位アドレスを読みかえ、それぞれ 0x3F215054, 0x3F215040 となる。

ステータスレジスタについて

AUX_MU_LSR については、BCM-ARM-Peripherals.pdf の 15 ページ目に説明が書いてあるみたい。

プログラム作成

/**
 * Mini Uart 送受信に使用するレジスタ。
 *
 * 書き込むと送信 FIFO にプッシュ,
 * 読み込むと 受信 FIFO からポップしてくれる素敵仕様らしい。
 */
#define MU_IO (*(volatile unsigned int *)0x3F215040)

/**
 * Mini Uart 送信 FIFO の状態確認をするための情報が入ったレジスタ。
 *
 * 6 ビット目 : Transmitter idle, アイドル状態か?
 *              1: アイドル状態, 0: ビジー状態
 * 5 ビット目 : Transmitter empty, 1 バイト以上送信受付可能か?
 *              1: 可能, 0: 不可能
 * 0 ビット目 : Data ready, 1 バイト以上受信しているか?
 *              1: 受信している, 0: 受信していない
 */
#define MU_LSR          (*(volatile unsigned int *)0X3F215054)
#define MU_LSR_TX_IDLE  (1U << 6) /* Transmitter idle のビットマスク */
#define MU_LSR_TX_EMPTY (1U << 5) /* Transmitter empty のビットマスク */
#define MU_LSR_RX_RDY   (1U << 0) /* Data ready のビットマスク*/

int main(void) {

    // 受信文字列格納用
    volatile char ch;

    while (1) {
        // 受信するまでビジーループ
        while (!(MU_LSR & MU_LSR_RX_RDY));

        // 受信データ記録
        ch = (char)MU_IO;

        // 送信受付可能状態になるまでビジーループ
        while (!(MU_LSR & MU_LSR_TX_IDLE) && !(MU_LSR & MU_LSR_TX_EMPTY));

        // IO レジスタにデータ書き込み
        MU_IO = (unsigned int)ch;
    }

    return 0;
}

配線

元ネタのページにも記載されているが、ピン番号はこちらで確認した。

まじめな人はこれと BCM2835-ARM-Peripherals.pdf を見比べて、 仕様書の見方に慣れていくのが良いかと。 (多分 102 ページ目からの説明とか 176 ページ目からの説明とかが対応する記述なのだと思う。)

購入した変換ケーブルの説明を見ると、下記のようになっている。

ブラックケーブル ----- GND
グリーンケーブル ----- TXD
ホワイトケーブル ----- RXD
レッドケーブル ------- VCC - 5V

というわけで、下記感じで配線する。

PIN  6(GND) ----- ブラック(GND)
PIN  8(GPIO14) -- ホワイト(RXD)
PIN 10(GPIO15) -- グリーン(TXD)

動作確認

  1. SD カードに bootcode.bin, start.elf, config.txt, kernel8.img をコピーして、Raspberry Pi に挿す
  2. PC に変換ケーブルを挿す
  3. シリアルコンソールを起動し、 Com の設定を行う(後述)
  4. Raspberry Pi に電源供給
  5. 入力文字がエコーバックされれば OK

シリアルコンソールについて

今回は、 RLogin を使用することとした。 sixel 関係で使っていて、使い慣れていたので。

設定は、下記のようにすれば OK のはず。

  • ビット/秒 : 115200
  • データビット : 8
  • パリティ : なし
  • ストップビット : 1
  • フロー制御 : ハードウェア

以上。

0 件のコメント: