アプリケーションからSAMA5D3 XplainedのUART端子にアクセスして外部ペリフェラルを操作する実験を行いました。マイコンとして使う上でUARTは大変重要なインターフェースですので、どんな具合にアクセスできるのかはきちんと知っておく必要があります。
なお、確認にはLEDボードを利用しました。
利用したLED
実験にはスイッチサイエンスで購入したシリアル接続7セグメント4桁LEDを使用しました。この製品はsparkfunが詳細なデータシートをgithubで公開しており、必要な情報を簡単に得ることができます。
また、UARTの他にSPI/I2Cの接続にも対応しているため、今回のようなマイコンを使う上の肩慣らしを行う際に大変津便利な製品です。今回の実験はUARTによるデータ送出実験ですので、電源の他は信号線を一本接続するだけで準備が整います。
UARTで接続する場合、9600baud, 8bit, non-parity, 1 stop bitで使用します。
UARTポート
SAMA5D3 Xplained (以下SAX)のUART TXポートは、J18ピンヘッダの8番ピンを使います。大変紛らわしいのですが、7番ピンには1とシルクスクリーン印刷してあります。隣にTXD0と有りますのでの間違うことは無いと思いますが、困ったことです。このピンと、LEDのRX信号をジャンパでつなぎます。
TXD0信号は、下の図に引用したように、SAXのUser ManualによればSoCのPC29に割り振られているURXD0です。
UART0はSoCのデータシートによれば0xF002_4000番地に配置されています。このUARTがLinux上でどのデバイスに割り当てられているかは、dmesgで確認できます。
root@sama5d3-xplained:~# dmesg | grep tty
[ 0.000000] Kernel command line: console=ttyS0,115200 mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs rw video=LVDS-1:800×480-16
[ 1.440000] atmel_usart f001c000.serial: ttyS1 at MMIO 0xf001c000 (irq = 30, base_baud = 4125000) is a ATMEL_SERIAL
[ 1.440000] atmel_usart f0020000.serial: ttyS2 at MMIO 0xf0020000 (irq = 31, base_baud = 4125000) is a ATMEL_SERIAL
[ 1.440000] atmel_usart f0024000.serial: ttyS5 at MMIO 0xf0024000 (irq = 32, base_baud = 4125000) is a ATMEL_SERIAL
[ 1.450000] atmel_usart ffffee00.serial: ttyS0 at MMIO 0xffffee00 (irq = 43, base_baud = 8250000) is a ATMEL_SERIAL
[ 1.830000] console [ttyS0] enabled
root@sama5d3-xplained:~#
ちょっと見づらいですが、0xf0024000番地のデバイスがttyS5となっていることが分かります。これで、J18ピンヘッダの1ピンは/dev/ttyS5から使用できると分かりました。
実験
Linuxから使うべきデバイスは/dev/ttyS5で、9600baud, non-parity, 1 stop bitと分かりました。早速実験してみましょう。
実験はpythonインタープリターを使います。このインタープリターはver2.7がatmel-demo-imageの中にデフォルトで含まれています。
Python 2.7.9 (default, Sep 5 2015, 19:22:49)
[GCC 4.9.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import serial
>>> ser = serial.Serial( ‘/dev/ttyS5’, 9600)
>>> ser.write(‘bfin’)
>>> ser.close()
>>>
処理はあっさりしたもので、ポートを開いて文字列を出力するだけです。
serial.Serial()ポートを開くためのものです。デバイス名とボーレートの与え方は説明する必要は無いと思います。なお、その他のパラメータは略しています。回線の指定を略すと、9600baud, 8bits, 1 stop bit, non-parityとなります。なので9600も指定する必要は無いのですが、却って読みにくいので残しました。
serial.write()は文字列を出力します。今回使用したLEDモジュールは与えられた文字になるべく合理的な解釈をしようとします。この例で言えば、’bfin’という文字列をなんとかLEDで表示しようと試みます。
結果
以下のように文字を出力できました。なお、shell上からechoを使って出力すると、改行文字まで表示されるため上手くいきません。