PIC18F67J60を使用しEtherNet対応機器を作る

昨今この様な電子工作を嗜む方は、家庭内LANがあると思いますし、WLANへの発展も可能なので、PICをEtherNetに接続する方法を学ぶと可能性が広がると思います。
早くアプリケーションを完成させたいだけなら、Linuxの動くマイコンボードが安価に手に入るようになったので、そちらを使った方が手っ取り早いとは思います。とはいえ、単純な監視や制御の用途にはいささかオーバースペックですし、コスト、サイズ、電力などの面で、「大は小を兼ねない」事も多いのも事実です。
というわけで、PHYが組込まれたPIC18F97シリーズを用いたEtherNet対応アプリケーションの使い方を、簡単なサンプルを例にまとめてみました。
詳細はMLA(後述)のドキュメントに詳しく書かれているので、基本をマスターしてしまえば応用は難しくないと思います。

H/W

概要

Microchip PIC18F97J60シリーズはEthernetモジュールを備えた、8bitのPICマイコンです。
64/80/100-pinパッケージがありますが、今回はピン数は必要ないので、64-pinパッケージを用いました。QFPパッケージのみの提供なので、今回は基板を外注して直づけする事にしました。

過去に、4チャネルの漏水センサーを作ったことがあったので、これをベースとして、4接点入力のスイッチと4つのLED出力、圧電ブザーを備えたボードとしました。LEDはSMDとアキシャル部品が選択可能です。

応用が効くよう、余ったピンのうち16本を自由に取り出せるようにしてありますので、LCDやUSBなどを追加して、より複雑なアプリケーションの開発も可能です。

ブロック図

EtherNetモジュールを使う場合、クロックは25MHzの外部クロックが必要です。また、電圧は3.3Vが必要なので、300mAのレギュレーターで生成し、全てこの電源を利用して動作させる構成にしました(EtherNetモジュールとその他の動作電源を分ける事も可能)。
この状態でも5V GPIOとの接続は可能です。

接点入力はトランジスタのバッファを設け、短絡時はGPIOがGNDに落ちる回路としました。

pullup抵抗は省略し、GPIOのWeak Pullup機能を用いてPullupを行います。

圧電ブザーは、大きな音で鳴ならすため、出力を2個用いて、それぞれHi/Lowを反転させます。出力にはPWMドライバを利用出来るよう、P3A,P3Bに接続してあります。

回路図

RJ45コネクタにパルストランスやコモンモードフィルタを内蔵したものがあるので、それらを利用します。EtherNetコントローラー側にLink/Act LEDの制御機能もあるので、LEDも実装されている製品を選択します。この辺は、データシートのサンプル回路そのままです。
EMI対策のため、Low Pass Filterを取り付ける事が推奨されているので、これはワンチップのπ型フィルタを採用 ました。フィルタは無くても、試作するうえでは支障はないと思います。

50Ωの抵抗噐は入手しづらいので51Ωで済ませました。

RJ45コネクタのACT LEDの極性が、製品によって逆になっているものがあるので注意してください。

基板

PCB

S/W

仕様

フローチャート

Microchip TCP/IP Stack

The Microchip Libraries for Applications (MLA)の一部として、TCP/IP Stackが提供されています。IPパケッ トやTCP/UDPフレームの詳細、また、主要なサーバークライアント型アプリケーションのプロトコルを知らなくても、アプリケーションを開発できるという便利なライブラリです。
MLAには他にも色々な機能のライブラリが含まれますが、ここではTCP/IP Stackにのみフォーカスしていきたいと思います。

サポートしているプロトコル

プロトコル以外のサポートライブラリも含まれてますが、ドキュメントにあるものをそのまま抜粋しておきます。

NameDescription
AnnounceProvides a UDP MAC address announcement feature.
ARCFOURImplements the ARCFOUR bulk encryption cipher.
ARPProvides Address Resolution Protocol support.
Berkeley (BSD) SocketsProvides a BSD socket wrapper to the Microchip TCP/IP Stack.
DNS ClientProvides Domain Name Service resolution.
Dynamic DNS ClientUpdates an external IP address to a Dynamic DNS service.
HashesCalculates MD5 and SHA-1 hash sums.
HelpersProvides several helper function for stack operation.
HTTP2 ServerProvides an advanced embedded web server.
ICMPProvides Ping functionality.
MPFS2Provides a light-weight file system.
NBNSDescribes the NetBIOS Name Service protocol.
Performance TestsTests TCP and UDP performance of an application.
SMTP ClientSends e-mail messages across the internet.
RebootProvides a service to remotely reboot the PIC.
RSAPerforms public and private key encryption routines.
SNTP ClientObtains absolute time stamps from a pool of network time servers.
SSLImplements SSL encryption for TCP connections.
TCPImplements the TCP tdansport layer protocol.
TelnetDescribes the operation of the Telnet module.
TFTPDescribes the TFTP module.
Tick ModuleProvides accurate time-keeping capabilities.
UDPImplements the UDP tdansport layer protocol.

インストール

Microchipのwebページに行くと、Current MLAとLegacy MLAと呼ばれるバージョンが存在する事がわかる。PIC18FはCurrent MLAでサポートされているようにwebページやリリースノートからは読める。
しかし、色々調べていくと、ETH97J60.h, ETH97J60.cが必要であり、これがCurrent MLAには含まれていない為、Microchipに確認してみたところ、「Legacy MLAとMPLAB C18を使用してください。」との事。

MLA v2013-06-15をインストールすると、C:/microchip_solutions_v2013-06-15/にインストールされますので、ここから適時コピーして使用します。
Microchip/TCPIP Stack配下にソースファイルが、Microchip/include/TCPIP Stack配下にヘッダーファイルが置かれている。また、Microchip/Common以下のファイルも一部必要になります。

最低限必要なファイル

本アプリケーションで必要とされるファイルについてリストしておきます。
TCPIP StackはDHCP, HTTP, ICMPを利用していますが、他のプロトコルを実装する場合は必要に応じて変更します。(詳細はドキュメント参照)
その他のファイルの詳細については、後述します。

1自前で用意する必要があるファイル。
2ETH97を使用する場合に必要。
3MPFSを使用する場合に必要。
4動的webページを使用する場合に必要。

基本的なプログラムの書きかた

具体的なプログラムの実装の話に入る前に、TCPIPStackの使い方について確認しておきます。

プロジェクトへのStackの追加

まず、
C:\microchip_solutions_v2013-06-15\Microchip/Microchip/TCPIP Stack
C:\microchip_solutions_v2013-06-15\Microchip/Microchip/Include/TCPIP Stack
をプロジェクト直下にコピーする。
必要なファイルのみをコピーしても勿論構わないが、面倒なのでこのようにしている。プログラムの配布時など、サイズをおさえたい場合は、余計なファイルは削除すると良いだろう。IDE上のプロジェクトには必要なファイルのみを追加すればよい。

メインプログラムはプロジェクトディレクトリ直下に置いた。
TCPIPConfig.hは少し工夫が必要。(後述)

メインプログラム

各プロトコルやスタックは並列に処理される必要があるが、スケジューラーなどという高等なものは用意されていないので、それぞれの初期化後、Stackやアプリの処理は無限ループでラウンドロビンに呼び出す必要がある。また、TickUpdate()を割り込みで呼び出す必要がある。 アプリケーションはステートフルとして、処理は短時間で終了するように実装する。

sleepやtimerを使ってdelayを設けると、task処理のスケジューリング問題が起きるので、TickGet()で現在時刻を取得し、特定の時刻まで待つ様な実装にする。
StackTaskはパケット送受信、StackApplicationsは各サーバーなど必要な関数を呼出す。必ずしも毎回callする必要はないが、StackTaskの呼出しが少いとスループットの低下を、StackApplicationsの呼出しが少いと想定外の結果を生じる場合がある。

TCPIPConfig.h

TCPIPConfig.hはTCPIP Stackの設定ファイル。デモプロジェクトからコピーして編集するのが良い。使用するプロトコルの設定、外部ROMを使う場合のアドレス、EtherNetコントローラーの設定、EtherNet用のRAMの設定、MACアドレスやIPアドレスの設定などが含まれる。

TCPIP ETH97.hをベースにした際の変更点はこちら。
EtherNetコントローラーの設定は適切になっているので、MPFSの置き場所を内部ROMに変更して、余計なプロトコルをDisableにしています。

他のファイルでは#include "TCPIPConfig.h"となっているのに、TCPIP.hの中で#include "TCPIP Stack/TCPIPConfig.h"されているため、TCPIPConfig.hをMLAと別のディレクトリに置いて、Includeディレクトリを指定しただけでは読みにいかない。
勿論、TCPIP.hを修正するか、Microchip/TCPIP StackにTCPIPConfig.hを置けば読み込めるが、TCPIPConfig.hはMLAとは別のディレクトリに置いておきたいし、TCPIPConfig.hを毎回修正するのも面倒だ。
そこで、プロジェクト直下にTCPIP Stackディレクトリを作り、この中にTCPIPConfig.hを置く。さらに、Project Properties -> mcc18 -> Include directoriesに次のディレクトリを追加する。
Microchip/Include
Microchip/Include/TCPIP Stack
TCPIP Stack

HardwareProfile.h

アプリケーションを幾つかのH/Wに対応させる場合に、このファイルにH/W依存の設定などを記述する。必ずこのファイルが必要という訳ではないので、他のファイルに含めても良いが、動作クロックをTCPIPStackに知らせる為、次のマクロ定義はやっておく。
私は、Configuration Fuseの設定と、GPIOのマクロ定義などもこのファイルに含めた。


#define GetSystemClock()	(41666667ul)
#define GetInstructionClock()	(GetSystemClock()/4)
#define GetPeripheralClock()	(GetSystemClock()/4)

HTTP2で使用する固有のファイル

webサーバーを動作させる場合、当然webページそのものと、動的な値を埋め込む仕組みが大抵必要になる。HTTP2では、webページそのものは、MPFS2ファイルシステム上に置かれ、このイメージはhtmlから、ユーティリティで生成する。また、ダイナミックなページの生成の為HTTPPrint.hとCustomHTTPApp.cを用意する必要がある。
MPFS2 utilityがweb pageのイメージ(外部メモリに置くか、PIC RAMに置くかによってファイルは異なる)とHTTPPrint.hは自動生成される。

さて、動的な値を埋め込む方法だが、html内に~変数名~で、動的に変化する変数を記載しておき、CustomHTTPApp.c内で、HTTPprint_変数名()という関数を記述しておくと、htmlファイルが参照された際にこれらの関数が呼び出されるという仕組みだ。

ディレクトリ構造

Trouble

私が遭遇したトラブル、嵌りポイントについて記述しておく。

mac.hでエラーが出る

mla/tcpip/mac.h:64: error: (141) can't open include file "eth97j60.h": No such file or directory

current MLAにはこのファイルは含まれていないので、LegacyMLAをダウンロードしてそこからETH97J60.h, ETH97J60.cをコピーした。

tcpip/mac.h:147: error: (103) #error: Warning, Ethernet RX buffer is tiny.  Reduce TCP socket count, the size of each TCP socket, or move sockets to a different RAM

tcpip_config.hを次のように変更。
#define TCP_ETH_RAM_SIZE (3900ul)

Source files

pic_nic3.zip

組み立てキット

基板を外注したり、部品が一部余ったりしたので、組み立てキットを販売する事とした。メール頂ければお分けします。

PIC,フェライトビーズ以外は秋葉原や通販で入手可能なので、是非組み立てからトライして頂きたい。
組み立てマニュアルはこちら