ORANGE pico の uartput が完了するタイミング

[ORANGE pico](http://www.picosoft.co.jp/orange/) には、文字列をUARTで送信する `uartput` コマンドがある。
今回は、この `uartput` コマンドの処理が完了し、次の処理に移るタイミングを観察してみた。

# プログラム

`uartput` を実行している間、PORT1 に HIGH を出力する。
この処理をサブルーチンとし、様々な長さの文字列を出力してみる。

```
10 ioctrl 1,0:out 1,0:goto 30
20 out 1,1:uartput 1,data$:out 1,0:pause 100:return
30 data$="1":gosub 20
40 data$="12":gosub 20
50 data$="12345678":gosub 20
60 data$="123456789":gosub 20
70 data$="1234567890":gosub 20
80 data$="1234567890123456":gosub 20
```

# 実行結果

`uart 1,2,9600` を実行し、通信速度を 9600bps に設定してから実行した。
すると、[ロジックアナライザ](https://www.switch-science.com/products/7642)により以下の波形が得られた。

![波形全体](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/8bc03cca-0175-b6d9-f091-bf28df7bc238.png)

以下、それぞれの文字列の出力の様子を詳しくみていく。

## 1文字の文字列の出力

UARTへの出力が続いている中、PORT1 がすぐ LOW になっており、`uartput` の処理がすぐに完了していることがわかる。

![1文字の文字列の出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/805049af-ea54-8fe9-8938-dd5c8d42902d.png)

PORT1 が HIGH になっていた時間は 80.5μs であった。

![1文字の文字列の出力 詳細](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/271aa452-121c-a7d4-b303-ef64fdfb7b32.png)

## 2文字の文字列の出力

2文字出力しても、`uartput` の処理はすぐに完了した。

![2文字の文字列の出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/f7307fa4-e2ce-b7b0-cce4-cbc2c376bb77.png)

PORT1 が HIGH になっていた時間は 74.0μs であった。
今回1文字出力したときよりも時間が短くなっている。
割り込み処理のタイミングの影響などの可能性が考えられる。

![2文字の文字列の出力 詳細](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/9a587e1e-d3cf-92c1-57bf-fe8970cd766b.png)

## 8文字の文字列の出力

8文字出力しても、`uartput` の処理はすぐに完了した。

![8文字の文字列の出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/bc3931ef-115d-b7aa-006b-f983e5896616.png)

PORT1 が HIGH になっていた時間は 87.2μs であった。
今回の測定において、1文字出力したときよりは長くなった。

![8文字の文字列の出力 詳細](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/351adf94-2b38-a3e4-4865-d4287b22d418.png)

## 9文字の文字列の出力

9文字出力しても、`uartput` の処理はすぐに完了した。

![9文字の文字列の出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/cb0aadfe-1e60-1401-d3a8-292aba1f9b9f.png)

PORT1 が HIGH になっていた時間は 91.8μs であった。
今回の測定において、8文字出力したときよりも長くなった。

![9文字の文字列の出力 詳細](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/d61302d2-aa1f-8ae0-4346-43cd4d787cee.png)

## 10文字の文字列の出力

10文字出力すると、`uartput` の処理はは最初の1文字の送信が完了したあたりで完了した。

![10文字の文字列の出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/ccec7d96-d459-4908-7aed-1694da48301c.png)

PORT1 が HIGH になっていた時間は 1127.0μs であった。
9600bps で1文字 (10ビット) 送信するのにかかる時間は 1041.7μs であり、これを除くと 85.3μs となる。
これは今回9文字出力したときよりも短い。

![10文字の文字列の出力 詳細](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/8ea7a113-5e51-5565-91ca-55fd379e5a68.png)

## 16文字の文字列の出力

10文字出力すると、`uartput` の処理はは最初の7文字の送信が完了したあたりで完了した。

![16文字の文字列の出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/2a70a501-ec24-cb35-f462-8dca835c0834.png)

PORT1 が HIGH になっていた時間は 7351.3μs であった。
9600bps で7文字 (70ビット) 送信するのにかかる時間は 7291.7μs であり、これを除くと 59.6μs となる。
この時間は、今回の2文字の出力時の時間よりさらに短い。
「すぐに完了した」ときでも PORT1 が HIGH になっていてかつ送信中の時間が存在し、これに相当する部分まで引かれてしまうのが「すぐに完了した」ときと比べて短くなりすぎる原因であると考えられる。

![16文字の文字列の出力 詳細](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/4e06f5ab-2a96-221e-324e-538275183baa.png)

# 結論

ORANGE pico の `uartput` の処理は、送信が残り9文字以下になったときに完了する。
これには、以下の理由があると考えられる。

* ORANGE pico で使用しているマイコンの PIC32MX シリーズの UART ペリフェラルには、8バイトの送信バッファがあり、送信中の1バイトを含めて9バイトのデータを貯めておける。
* ORANGE pico のソフトウェア側では送信バッファを用意せず、`uartput` はデータをハードウェアに渡せる状態になるまで待機する。