シリアル怪奇現象の正体見たり、「使用しているライブラリの仕様には注意」
先日、FPGAにシリアル接続すると、データが化けるという怪奇現象が発生することがわかりました。
原因が不明でオシロスコープやロジアナでみないといけない(持ってないですが)と思ったのですが、 識者の方からのコメントではボーレートがずれて、最後のStopbitを拾っているということでした。
というわけで、いろいろ試して原因を探してみることにしました。
uartについて38Kbpsに速度落として確認
--> 結果は115.2Kbpsと同様にNGでした。。Parity CheckとStop bit用の待ちサイクルを1サイクル分伸ばしてみた。
(待ちサイクルが短いからParity bitで0を拾って開始されてしまったのではと想像) --> NG。Loopbackすら失敗しました。。。
1, 2より、シリアルの転送速度依存ではなく、またParity check, stopbitの長さは関係ないことがわかりました。 となると、そもそものクロック周波数が125MHzと想定していたのが100MHzだったりするのではと思いました。 そうなると残念ながら、クロック周波数測定の方法がないので、測る装置を購入するかしないといけない状況です。。
どうしたものかな。。 と思いました。
ぼんやりと、シリアル転送のタイミングチャートを見ていて、ふと 今回パリティは使っていないなと気付きました。 使っていないときには、Parityは送信不要とも思えました。 もし、Parityを送っておらず、skipしてStop codeを送ると、想定する受信データは1つずれることになります。
先日コメント頂いた内容で、最後のStop bitを拾っているという言葉がキラリ光りました。
「もしかして、PythonのSerialライブラリのParityとStopの扱いが想定と違うんじゃないのでは?」
pySerial API — pySerial 3.0 documentation
class serial.Serial __init__(port=None, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, write_timeout=None, dsrdtr=False, inter_byte_timeout=None) parity – Enable parity checking. Possible values: PARITY_NONE, PARITY_EVEN, PARITY_ODD PARITY_MARK, PARITY_SPACE stopbits – Number of stop bits. Possible values: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
↑のサイトを調べて驚愕でした。Serialライブラリのデフォルト設定はParityは送付しない、Stop bitは1つ送信と 想定していたものと2bit分異なっていたんです。(想定はparity 1bit, stop 2bit)
ということはです。想定に近づけるために、parity 1bitにする、あるいはstop 2bitにするとどうなるのか? 試してみました。
「PASSしました」
-ser = serial.Serial('/dev/tty.usbserial-14310', 115200, timeout=1.0) +ser = serial.Serial('/dev/tty.usbserial-14310', 115200, timeout=1.0, parity=serial.PARITY_ODD) # stopbits=serial.STOPBITS_TWO
怪奇現象の正体
- pyserialライブラリのデフォルトはparity 1bitがなく、stop bitは1bitだった。
- 一方でFPGAのシリアル受信器はparity 1bit, stop bitは2bit(実際は半サイクルwait)想定だった。
- 1, 2より、データ部分が半サイクルずれることになり、データとして1bit前後した。
1bit後: stop bitを拾ったために0x80に1bit右シフトした結果が出た。(0x80,0x80, 0x81, 0x81..)
1bit前: 0x80が消えて1bit左シフトした値が出力されるようになった。(0x1,0x3, 0x5..)
あとがき
送信側(今回はSerialライブラリ)の仕様を理解していなかったことで、今回の現象が生じました。 とても基本的なことなので、お恥ずかしい限りで情けない限りです。
使用しているライブラリの仕様には注意しようと誓いました。