LPC1114FN28/102 (17) -- ICSP 接続で PIC32MX のフラッシュに書き込む (2)

前回の記事の最後に示した図を下に再掲しますが、これは Microchip 社のドキュメント

PIC32MX Flash Programming Specification
(DS61145 Revision K, July 2012)

の pp.13 「Figure 5-4」を書き直したものです。
JTAG の 1 クロック分と、2-wire 4-phase ICSP の 4 クロック分との対応関係を示すものですが、元の図では、ICSP の 4.5 クロック分の区間との間に破線が引かれており、不明確です。
そこで、正しいと思われる範囲の 4 クロック分にぴったりと合うように書き直しました。
また、元の図では PGEDx の波形の中に「TDI=IR0」のような記述がされていますが、スペースが足りなかったので、波形の中には「TDI」のみを書き、その下に「= IR0」のように記してあります。

図の上半分には、JTAG

  • TCK (Test ClocK)
  • TMS (Test Mode Select)
  • TDI (Test Data Input)
  • TDO (Test Data Output)

の信号の波形が示してあります。
動作としては、まず、TMS 1 - 1 - 0 - 0 シーケンスで TAP (Test Access Port) コントローラを「Shift-IR」ステートに設定し、5 ビット幅のインストラクション・レジスタに TDI 経由で値をシフトインしています。
図ではその LSB の値を示す「IR0」と、MSB の値を表す「IR4」だけが示されており、途中の IR1 〜 IR3 の部分については省略されています。
MSB である IR4 のタイミングで TMS=1 として「Exit-IR」ステートに移行し、続く TMS 1 - 0 シーケンスで、さらに「Update-IR」ステートを経由して「Run-Test/Idle」ステートに戻っています。
ICSP との対応としては、TDI から「IR0」を送出する 1 クロック分の区間について示されています。
さらに、半周期分 (TCK 1/2 クロック、 PGECx 2 クロック) 過去に遡る領域も示されています。
ここでの一般的な話では、JTAG/ICSP 経由で操作される対象の方を「ターゲット」、JTAG/ICSP の信号を供給する方を「JTAG プローブ」と呼ぶことにします。
ICSP 側では、最初の PGECx クロックで TDI の値を、続く 2 番目の PGECx クロックでは TMS の値を PGEDx にこの順で乗せます。
PGECx の立ち上がりエッジで PGEDx 上のデータが変化し、ターゲット側では PGECx の立ち下りエッジで PGEDx 上のデータをサンプルして取り込みます。
このタイミングは SPI (Serial Peripheral Interface) のモード 1 と同じです。
続く PGECx 2 クロック分の時間で TDI のデータ転送が行われますが、TDI/TMS とはデータ転送方向が違うので、ターゲット側 / JTAG プローブ側のいずれも入出力の切り替えが必要になります。
信号の衝突を防ぐために、3 番目の PGECx の前半と、4 番目の PGECx の後半の期間は両者ともハイ・インピーダンス状態 (スリーステート) にして、どちらからもドライブされないマージンの期間としています。
TDO については、PGECx の立下りエッジのタイミングから出力され、JTAG プローブ側では 3 番目と 4 番目の境界の PGECx の立ち上がりエッジでサンプルし、取り込みます。
このタイミングは SPI のモード 0 に相当します。
PIC32MX のスペック上は、PGECx の最大クロック周波数は 10 MHz (1 周期 100 ns) なので、この周波数領域までを対象にするなら、スリーステート切り替えのためのハードウェアが必須となります。
ただし、JTAG でなく ICSP 経由でアクセスする場合には CPU コアは内部 8 MHz クロックで動作するため、後述する PE (Programming Executive) を使ってプログラミングする場合、クロックは 1 MHz が推奨されるという下のような記述があります。 ("PIC32MX Flash Programming Specification" 31 ページ)

16.1.1 2-WIRE ICSP EJTAG RATE
In Enhanced ICSP mode, the PIC32MX family devices
operate from the internal Fast RC oscillator,
which has a nominal frequency of 8 MHz.
To ensure that the programmer does not clock
too fast, it is recommended that a 1 MHz clock
be provided by the programmer.

1 MHz 程度のクロック・レートで良ければ、ソフトウェアでクロックやデータをトグルしても実現可能ですから、その場合にはスリーステートのコントロールもできます。
ここでの実験では、ソフトウェアによる実現は採用せず、LPC1114 の SPI の 4 ビット転送モードを利用しています。
と言うより、LPC1114 (や LPC17xx や LPC23xx など) の SSP (おそらく ARM 製の IP) には 4 ビット転送モードがあるのを見つけて、2-wire 4-phase ICSP に都合が良いんじゃないかと思ったのが始まりです。
普通の SPI を使うので、もちろんスリーステート・コントロールなどはありませんから、単純に抵抗による合成でデータ転送方向切り替えを実現しています。
正確に言えば、切り替えではなく、信号強度による「オーバーライド」です。
ターゲットの PIC32MX の PGEDx には、LPC1114 の MOSI と MISO から、それぞれ 1 kΩ の抵抗を介して接続されています。
前半 2 クロックでは、PGEDx は入力モードでハイ・インピーダンスですから、1 kΩ の抵抗があってもストレー容量による遅延が加わるだけで MOSI 出力からの TDI/TMS 出力のレベルはそのまま PGEDx および MISO に伝達されます。
後半 2 クロック (のうち 1 クロック分) では、PGEDx は出力モードとなり、TDO の値を出力します。
MOSI 出力とは 1 kΩ の抵抗を介して接続されているので、ふたつの出力同士がケンカすることになります。
しかし、MISO 入力は PGEDx 側とつながっていますから、MISO 入力側から見た出力インピーダンスは、

となりますから、出力インピーダンスの低い PGEDx 側の出力が優勢となり、MOSI 出力の影響により、 GND / VDD レベルからは少し浮いているけれどもロジック値としては PGEDx の値が MISO に入力されます。
ここで問題となるのは、モード 1 で動作している SPI では PGECx の立ち下りで MISO 入力を取り込みますが、同じタイミングで PGEDx はスリーステートに移行するのでホールド・タイムが不足する可能性があります。
LPC1114 のスペックでは、このホールド・タイムの最小値は 0 ns なので、実際には問題となりません。
この抵抗とストレー容量で構成される「1 次 RC フィルタ」により波形が「なまる」ので、高速動作をさせたい場合には抵抗値を小さくする必要があります。
すぐ後で示す写真のように、配線長の短い実験基板上の 1 MHz クロックでは、1 kΩ 程度でも十分なようです。
実際に 30 cm 程度のフラット・ケーブルを用いてターゲット側と接続するような場合を考えると、ストレー容量が増えるので、その場合は見直しが必要かも知れません。
PGECx 側は直結でも良いのですが、ターゲット側に書き込まれたプログラムが走りだして PGECx を出力に設定する場合を考え、保護用に 220 Ω を挿入しています。
また、PGECx/PGEDx 以外に MCLR も制御する必要がありますが、LPC1114 側の端子としてはオープンドレインの PIO_5 を使っています。
オープン・ドレインであれば、MCLR 端子をリセット SW で直接 GND に落とされても問題ありません。
実際の波形写真を下に示します。

上側のトレースが PGEDx 端子での波形で、下側のトレースが PGECx 端子での波形です。
本来のストレー容量のほかに、オシロのプローブの入力容量も加わった状態を見ていることになります。
PGECx のクロック周波数は 1 MHz です。
時間軸について欄外に「M 5 μs」、「D 500ns」という 2 つの数値が表示されていますが、「遅延掃引」で見ているので、時間軸は 500 ns/div です。
この波形から

  • TDI = 0
  • TMS = 1
  • TDO = 1

ということが読み取れます。
MOSI 出力は、後半の 2 クロック部分は「0」を送出しているので、本来はスリーステートになるはずの区間の値は「0」になっています。
PGECx の 3 番目の立ち下りエッジから TDO の値が出力されています。
これは PGEDx 端子からダイレクトに出ているので、波形の立ち上がりがシャープになっています。
それに対して、PGECx の 4 番目の立ち上がりエッジから PGEDx がスリーステートになるので、MOSI 出力側が勝つことになるのですが、1 kΩ とストレー容量で構成された 1 次 RC フィルタを介しているので、電圧レベルの変化は急ではなく、ゆるやかです。
最初の JTAG と ICSP との対応の図に戻りますが、もうひとつ注意すべき点があります。
それは、TDO の出力されるタイミングが JTAG と ICSP とではズレているということです。
上の図の例では、JTAG で TDI に「IR0」が乗るタイミングで TDO から「1」が出力されるものとしていますが、ICSP では、それに対応する「1」は、「前」のサイクルに出力されています。
図では ICSP の前のサイクルの 2 クロック分だけを示してあり、「pTDO」と記されている部分が相当します。
ICSP の「TDI=IR0」のサイクルでは「nTDO」の部分に、 JTAG の「TDO=IR1」 のサイクルでの TDO に相当する値が出力されています。