EtherCAT開発方法 フレーム編（ライトまで）

この記事は [EtherCATについて語る Advent Calendar 2019](https://adventar.org/calendars/4097) の10日目です。
昨日は@nonnoiseさんの [EtherCAT開発方法 フレーム編（リードまで）](https://qiita.com/nonNoise/items/bbe1689344ccc7b8ace0) でした。


#はじめに
ん〜前回の[EtherCAT開発方法 フレーム編（リードまで）](https://qiita.com/nonNoise/items/bbe1689344ccc7b8ace0) を書きなぐりのようにまとめたけど、ちょっとマニアック過ぎて、知りたいのはそこじゃない感を感じたりしてるんだが・・・

ただ、まぁEtherCATを通る上ではEtherCATのコアレジスタにアクセスしなければならないし、そこを触れていなくても間接的には利用している訳で、そういった意味で前回と今回の内容は大事なので、取り敢えずまとめておきます。


##ArtifactNoise開発モデル
この先の内容は、以下の環境を元に説明していきます。
- Raspberry Pi 3B+ (4BやJetson Nano、Ubuntuデスクトップなど)
- [PyEtherCAT](https://github.com/pyEtherCAT)
- [EtherCATスレーブ評価基板LAN9252使用](https://www.switch-science.com/catalog/5917/)
- [LED16モジュール](https://www.switch-science.com/catalog/5918/)

**※本ライブラリは、WindowsやMac OSでは、セキュリティーの関係で動作しません。**

他の方法については、他の方々の方法を参考に。

#Write（ライト）方法

![スクリーンショット_2019-12-09_20-51-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/564af7ed-e9dc-a0ab-b99d-07b09b6ea853.png)
http://ww1.microchip.com/downloads/jp/DeviceDoc/00001909A_JP.pdf

さて、Write(書き込み)を行うには、まずレジスタが書き込みに対応している必要がある。多くのレジスタはRO（リードオンリー）となっており、RW（リードライト）となっている箇所、もしくはWO（ライトオンリー）の物を探す必要がある。なお、WOは滅多に無いのてここでは除外する。

レジスタの中で、著者が気に入っているレジスタが、**RUN LED オーバーライド レジスタ**である。

このレジスタは、本来正常に動いているRUN LED(EtherCATでは正常に動いている際にこのLEDが点灯する**決まり**)を、強制的に動作を変更するレジスタである。

早速、RUN LEDの状態を変化させてみよう。

前回と同じですが、以下の方法でライブラリをダウンロードします。

```
git clone  https://github.com/pyEtherCAT/EtherCAT_Master.git
cd EtherCAT_Master
```

以下のソースを書きます。

```python3:wrtittest.py
from pyEtherCAT import MasterEtherCAT #ライブラリの読出し
nic = "eth0" # ネットワークカードのアドレスを記載
cat = MasterEtherCAT.MasterEtherCAT(nic)  

ADP = 0x0000 #1台目
ADDR = 0x0138 #コアレジスタのアドレス
data = [0]*1
data[0] = 0x10 | 0x0D
cat.APWR(IDX=0x00, ADP=ADP, ADO=ADDR, DATA=data) #データ書き込み
(DATA, WKC) = cat.socket_read() #結果を読出し
print("[0x{:04X}]= 0x{:02x}".format(ADDR, DATA[0]))
#読み出したデータを表示する

```

結果〜

```
[0x0138]= 0x1d
```
![6a6ea962-d8b7-4947-b3ab-3cb3302b6f66.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/d94c40bd-0057-d1e0-d798-ede3e5423a75.jpeg)

こ↑こ↓が光る！！点滅るす！！

所謂、**Lチカやぁぁぁぁ！！！**

って事で、皆さんLチカが出来ましたね。

解説すると・・・

- **APWR**を使って自動インクリメント物理ライトリードで書き込んで読み込んでを行います。
- **ADP**は、自動インクルメントなので、機器に接続された１台目を読みにいきます。２台目を読む際は-1をします。
- **ADDR**は、コアレジスタのアドレスを指定します。RUN LED オーバーライド レジスタは**0x0138**なので、それを指定します。
- **DATA**には、オーバーライドを有効にするため4bitを1にする0x10と、その先のLED状態を点滅にする0x0Dを重ねています。
- **socket_read**は必要ありませんが、APWRは戻り値もあるので書き換えられたか確認の為、読み出してます。

という感じで、書き換えが出来ましたね。

#実は・・・・
このレジスタ辺りの資料を見ていくと、EEPROMで設定するレジスタという項目もあります。
![スクリーンショット_2019-12-09_21-30-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/ea33e1cb-55e5-8c5e-5d6a-e31362063075.png)

これは、**チップが起動時やリセット時に最初に読み出される内容**で、
本来はROのレジスタもEEPROMに書き込むことでビットを変更出来たりします。

自身が販売しているモジュールにはこのEEPROM周りは解決してGPIOとして設定していますが、正直ここが一番理解もデバックも動作確認も厳しく、説明もしづらく、いっそGUIソフトを作ったほうが良いのではないかと思っている所です。
EEPROM辺りは、来年の活動にご期待下さい！。

#裏技・・・?

![スクリーンショット_2019-12-09_21-36-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/d1ed739f-c948-448d-8084-fa13c5a964c8.png)

EtherCATコアレジスタに、ユーザーRAMが存在します。

正直、この先も深いEtherCATの機能に手を伸ばすよりも・・・このユーザーRAMを使ってオレオレEtherCATを作るって言う手も・・・いやいやいや。

取り敢えず、APRDとAPWRを駆使すれば、何とかEtherCATらしい事が出来るという事です。

#まとめ

さて、これでリードとライトが出来ました。
これでEtherCATがチョットワカルだね！！
・
・
・
ウソです。そんな事はありません。EtherCATの難しさはこれからです。
実はまだ自分も調べつくせてない機能で

*FMMUx*
*SyncManager*
*MailBox*
*ect・・・・*

EtherCAT上位層はほんと難しい。正直ここで十分な気もしつつ、
来年以降頑張っていこうかと思います。

ではでは・・・次回はデバック方法をまとめます！

北神 (@nonNoise)