2011年10月08日

Foca_V2.1

goodluckbuy.com を見ていてこんなのを見つけた。



http://www.goodluckbuy.com/ft232rl-tiny-breakout-foca-v2-1-usb-to-serial-uart-xbee-.html
FT232RL Tiny Breakout Foca V2.1 USB to Serial UART Xbee $10.32 (送料無料)

    これは何かというと XBee を PC で使うための UART ボード。5pin の端子も出ていて RxD/TxD/DTR を使って Arduino というか ブートローダを書き込んだ ATmega328p などに接続できるようだ。AVR の ISP っぽいコネクタのパターンもあり、どうも avrdude-serjtag でライタになるようだ。

    なかなか、良さそうなボードだ。特に ATmega328p のチップ単体を Arduino として使うには便利そう。ちなみに、サイズは、45mm x 20mm と書いてあるが 間違い。XBee の幅は、24.38mm 。-- データシートを見たら 45.72mm x 29.21mm と書いてあった。タカチ SW-55S にも収まるサイズ。

      データシートの 幅も間違い。やはり 25mm に近いはず。だが、下記の考察は、XBee の幅を元にしているので結論は変わらない。

    それはともかく、気になったのは、デザイン -- まるで小さな arduino のようではないか。
    なにか、Ardduio 風のものを 5cm x 5cm 以内で設計してみたくなった。これについて、あとで考えてみよう。

http://iteadstudio.com/store/index.php?main_page=product_info&products_id=94
FT232RL Tiny Breakout - Foca v2.1 $8.90

    さて、もうすこし調べたら オリジナルは、これだと分かった。iteadstudio.com というと Fusion PCB と全く同じサービスをしていたところ(今はちょっと違う?)。-- こんなボードまで開発していたのか。

    値段はちょっと安いが、送料は別にかかる。これだけを買うなら goodluckbuy.com のほうが安そうだ。



    http://iteadstudio.com/store/index.php?main_page=product_info&products_id=396
    [Bare PCB] Foca v2.1 (FT232RL breakout) Bare PCB $1.5

    ボード単体も売っている。裏面をよく見れば、まさに AVR ライタ用だとわかる。ちなみに、電圧は 3.3V or 5.0V で中央のスイッチで切り替えるようだ。

    あと、スライドスイッチやタクトスイッチは、日本で入手しやすいものではないかも知れない。ボードを買って自作する場合は、要注意。

    http://iteadstudio.com/store/index.php?main_page=product_info&products_id=329
    Slide Switcher 1P2T (10Pcs) $2.0

    スライドスイッチは、たぶんこれ。必須だから、ついでに買っておくべき。

    http://iteadstudio.com/store/index.php?main_page=product_info&products_id=334
    2.5mm SMT Momentary PUSH Button (10 Pcs) $0.7

    SMD 2 極のタクトスイッチはこれ。

    http://iteadstudio.com/store/index.php?main_page=product_info&products_id=376
    ET1117-3.3V(SOT-89) - 3.3V Positive Voltage Regulator (5 Pcs) $1.0

    3.3V レギュレータ。これも。

    http://iteadstudio.com/store/index.php?main_page=product_info&products_id=336
    Mini USB 5-Pin SMT Female Connector Socket (5pcs) $2.00

    USB miniB は、微妙。信頼性を考えると、日本製のパーツが使いたくなる。だが安い。ついでに買っておけ... という気もする。そう考え出すと 秋月より 安いものが多々ある。2.54mm ピッチのピンヘッダ・ピンフレームとか。沢山買い込みたくなる -- かなり危険だ。

    そもそもボードが安いからといって自作を考え出すのが危険な考えなのだ。製品があるのならすなおにそれを買っておくほうが安く済む。

arduino 風のボードについて

    MPU の条件は、実装面積から判断して USB をサポートしていること。そうなると ATmega32u2 か u4 しかない。u4 は、機能が豊富だからこれが候補。

    ATmega32u4 の Arduino -- Arduino Leonardo がもうすぐ出る。そういう理由からも u4 を使いたい。Arduino Leonardo は、低価格版とも言われているから、大きなサイズで良いのならすなおに使えば良いのだ。わざわざ自作する必要はない。

    ちいさなモジュールとしては、Adafruit 『Atmega32u4 Breakout Board+』 や 『Teensy』 がある。モジュールは、Arduino とは逆で ボードの上に載せるのが普通。

    Arduino 的に マザーとして使って、かつ小さいものがあっても良いかも知れない。Fusion PCB で 基板を作る場合 5cm x 5cm に収まると安くなるという事情もある。-- Arduino 本体やシールドの最小幅は 5cm をわずかにオーバーするので具合が悪い。



    実は、以前 ATmega32u4ボード を作った。このときは、その前の作品との互換性を考えてコネクタを短辺につけた。基板サイズは、47mm x 35mm ぐらい。1/2 に切った C 基板を付けられるようにしている。

    だが、コネクタを長辺につけて arduino 風にするのも面白いかも知れない。ちょっと考えてみよう。

    まずは、Foca を基準に考える。

      Foca_V2.1 の サイズは、45.72mm x 29.21mm 。XBee のためのコネクタは、2mm ピッチ で両サイド 1x10。
      2mm ピッチコネクタの 間隔は、22.0 mm 。

      思ったより幅が広い。 あと 2mm ピッチ はちょっと使いにくいかも。

    次に今まで作ったボードからの考察

      C 基板を 真ん中で切ると縦 47mm 横 35mm ぐらいになる。このサイズは、タカチ SW-55S に入るのだが、底面に置くには、幅がちょっと広い。幅 32mm ぐらいがちょうど良さそう。

      C 基板の短辺の端の穴の数は、13 。(次の列は 15 穴でその次から 17穴) 。1/2 に切ったときの 短辺の穴は最大 13 だが、1列分小さく作るなら 12 。

      このサイズ 17穴 x 12穴 分をベースにすると 43.18 mm x 30.48 mm のサイズになる。これに余白が必要で、C 基板が 47mm であることから計算すると 47mm x 34.3mm になる。だが、3mm φの穴をあけないなら、こんなに余白はいらない。... 1mm づつ四方を削ると 45mm x 32.3 mm 。(余白は、0.91mm)

    このエリアに Foca の パターンを置くと 左右が それぞれ 3.24mm あく。ここに 2.54mm ピッチのコネクタを置ける。3mm φの穴 を無視して、コネクタは、1x14 にすれば良いと思う。

      12穴ぶんのエリアの 左右に 2.54mm ピッチのコネクタを配置するとその内側は、10穴分 -- 25.4mm 。
      2mm ピッチのコネクタの厚みが 2.0mm だとすると .. 22.0 mm + 2mm = 24mm 。計 1.4mm の余裕があるはず。

    さて、Foca との関係はどうしよう。2.54mm ピッチのコネクタは、位置は違っても Arduino Leonardo と互換性があるようにしておきたい。その上で XBee 用 2mm ピッチを付けたいところだが、配線できるのだろうか?

    シリアル出力と ISP はどうしよう。ATmega32u 自体の ISP は必要だから付けるとして ... ライタとして使える ISP も付けたい。で、それを USART ベースにする。(TXD/RXD/XCK とあと 1つ) USART は SPI マスタとしても使えるから これが良いはず。

      そういえば、ATmega32u4 に対応した自製のブートローダ(USBasp 互換)とか、USBasp 互換 ライタも作ったのだった。USBasp 互換 ライタ は 未完ながら TPI/PDI に 対応させようとしていた。これらを使う上で問題ないようにしておかないと ... 忘れてはいけない。

      思い出した、TPI は 5V 対応でないといけない。手持ちのボードは全部 3.3V だからテストが止まったのだった。Foca と同様に 3.3V - 5V の切り替えスイッチを入れなければ。

    時間が取れたら、この構想をベースにして、基板を設計してみたい。

Arduino Leonardo のピンアサインとか

    stastaka's Blog の情報を元にすると...

      mega328p mega32u4 mega32u4 mega328p
      D0 PD0(RXD) PD2(RXD) PF0(ADC0) PC5(ADC5) A5
      D1 PD1(TXD) PD3(TXD) PF1(ADC1) PC4(ADC4) A4
      D2 PD2(INT0) PD1(SDA) PF4(ADC4) PC3(ADC3) A3
      D3 PD3(INT1) PD0#(SCL) PF5(ADC5) PC2(ADC2) A2
      D4 PD4(T0) PD4 PF6(ADC6) PC1(ADC1) A1
      D5 PD5(T1) PC6# PF7(ADC7) PC0(ADC0) A0
      D6 PD6(AIN0) PD7#
      D7 PD7(AIN1) PE6

      D8 PB0(ICP) PB4
      D9 PB1(OC1) PB5#
      D10 PB2(SS) PB6
      D11 PB3(MOSI) PB7#(RTS)
      D12 PB4(MISO) PD6
      D13 PB5(SCK) PC7#
      GND
      AREF
      SDA (?)
      SCL (?)

      TXLED PD5(XCK/CTS) PB0?
      HWB PE2

      D14 PB0(SS)
      D15 PB1(SCK)
      D16 PB2(MOSI)
      D17 PB3(MISO)

    転記ミスがあるかも知れないが ... まぁだいたいこんな感じらしい。# は負論理 -- ソフトでの処理のはず。ATmega332u4 では、TWI は、PD1/PD0 が割り当てられている。もとの SDA/SCL を省いてしまえば、16 pin/16 pin にできる。

    SPI は、コネクタに出ていないようだ。そうであれば、ライタ用の ISP コネクタに接続しておきたい。ただ、確定ではないから Arduino Leonardo の 回路図をみてから再考することにしよう。

      やはり、コネクタに出ていないのはおかしいような -- SPI をあてにしているシールドも多数あるはず。二重に接続するとかしているのだろうか? それとも低価格版ということで割り切っている?

      アナログスイッチで切り替える -- みたいな実装もありえるのだが... 写真をみてもそんな IC は載っていなさそう。

    一方 XBeeShield なるものが、ある。本来なら 互換回路を組み込むべきかも知れないのだが ... XBee使わないなら切り離さないといけないし ... ちょっと面倒そうな。

    ちなみに Foca の場合、TXD/RXD/RTS/CTS/DTR/DCD を接続して Xbee の RESET をボタンに接続している。

    ついでに、Seeeduino Stalker (Atmega 328) というのがある。これは、FT232R がないかわりに多数のデバイスを載せたもの。XBee も載せられる。

      Foca XbeeShield Stalker
      1
      2 DOUT RXD o RXD
      3 DIN TXD o TXD
      4 CD DCD
      5 RESET button button
      6 RSSI LED
      9 DTR DTR
      12 CTS CTS o
      15 LED
      16 RTS RTS
      17 AD3 AVR RESET(with Tr)

    信号線だけピックアップするとこんな感じ。XbeeShield は、あまり線を接続していない。

    ATmega32u4 には、CTS と RTS の信号線がある。これに加えて DCD/DTR を定義してつなげたい。
    ただ、Arduino Leonardo では、CTS が、LED 制御に使われているようだ。どうしたものか。

      Foca の XBee は、Host から使うのが前提。それに対し XbeeShield , Stalker は Slave 用で、配線の違いはそれが関係している。また、XbeeShield は、5V の Arduino に接続できるようになっているが、Foca, Stalker は 5V での XBee 使用 は考慮していないように見える。

      では、作ろうとしている Arduino 風のものは、どう考えるのが良いのだろうか? -- Host との USB 接続が特徴と考えれば、Host 向きの接続で良いはず。

    Arduino Leonardo の疑問点は、(1) SPI の扱い 、(2) TWI の扱い、(3) CTS の扱い。回路図が公開されたら、これらをチェックしよう。

独自配列の考察

    どうせ shield に互換性はないのだから、独自配列でも良いような気がしてきた。もとの Arduino も mega88 系に都合の良い配列だったのだ。配線面積が少ないのに、互換性を求めると 配線がスパゲッティになる。それに、互換にすると CTS とか困るケースが出てきそうだ。

    Foca V2.1 の機能を実現しつつ Ardino 風にする ということでも良いのかも知れない。コネクタを 2mm ピッチにして ピン数を増やし、XBee (Host)も載る みたいなのはどうだろう。こうしたほうが見栄えが良くなりそう。もちろん XBee を載せた場合は、他の目的には使えない。(これはもとから)。

    ただ、2.54mm ピッチも付かないと 使い勝手が悪い。2.5mm ピッチは変換基板のように 同じ配列で外側につけるとか。(ただし、配線が辛くなるので、平均 5ピン毎に 2mm ピッチの信号を間引く )

    ちなみに、2mm ピッチのピン・フレームは、背が低い。XBee のように 25.4mm - αの幅にしないと 2.54mm ピッチ の ピン・フレームと競合する。

    電圧の、3.3V / 5V 切り替えは必須。ただ、スライドスイッチの配置が難しいかも。

    Arduino として使うときは、定義ファイルを 作らないといけない? 互換性を捨てた代償がそれだけならば、これで行っても良いかも。

    追記: 定義ファイルは何だろう?

    https://github.com/arduino/Arduino/tree/new-extension/hardware/arduino

    たとえば、ここでソースコードをブラウズできるようだ。

    見てみると、『hardware/arduino/variants/leonardo/pins_arduino.h』というのがある。

    あと、『hardware/arduino/boards.txt

    この 2 つで事足りそう。

    leonardo.build.f_cpu=16000000L
    leonardo.build.core=arduino
    leonardo.build.variant=leonardo

    valiants/xxx/pins_arduino.h を作成し、build.variant を xxx に変更すれば、好きなピン配置にできるように見える。

XBee のピン配置のメモ


    3V3 1 VCC AIO x 20
    RXD 2 O DOUT AIO x 19
    TXD 3 I DIN AIO x 18
    X 4 x AIO x 17 X
    5 I RST RTS I 16 RTS
    6 O RSSI O 15
    7 I VREF I 14 AREF
    X 8 x reserved ON O 13 X
    DTR 9 I DTR CTS O 12 CTS
    GND 10 GND x 11

    上が Foca の USB 側、XBee はアンテナ側。

    内側が XBee の割り当て。x は、デフォルト disable で I,O はデフォルトの入出力。

    外側の X は、間引くところ(予定)。TXD などは割り当てる信号とか。それ以外は mega32u4 の信号を振っていく。コネクタは下に伸ばす。どこまで伸ばすかは未定。

Foca のディメンジョン



    この画像は、355 x 196 に縮小したもの。縦を 45mm とすると 1.77 inch これを x200 すると 354 -- 横は 0.98 inch - 24.9 mm という計算になる。

    さて、2mm ピッチを下に伸ばすとして... 1x20 は、入らない。1x16 ぐらいがせいぜい。
    横につける 2.54mm ピッチは、2mm を間引く。3pin 間引けば 1x13 だがパーツの都合では 1x14 が良い。8+6 もいけるし。あるいは、12 ?。

    2mm のピンフレームは、秋月だと
    http://akizukidenshi.com/catalog/g/gC-03669/
    http://akizukidenshi.com/catalog/g/gC-03871/

    の 2 種類がある。いずれも 1x20 で切って使わないといけない。XBee の分のみで良いなら 1x10 もある。

    iteadstudio.com だと こんなのがある。

    http://iteadstudio.com/store/index.php?main_page=product_info&products_id=119
    2.0mm 40Pin Female Header (5 Pcs) $1.50

    どうせ切るならこれで良いかも。

    ところでこれらは背が低い。プラスチック部:約4.3mm ? (2.54mmピッチは約 8.5mm) これだから Arduino 風に見えるのだ。
    デザイン優先で 2.54mm ピッチをなしにしたいところだが、そうもいかないだろう。

    2.54 mm 1x14 は秋月では、これ。
    http://akizukidenshi.com/catalog/g/gC-00653/

    iteadstudio.com だと、1x40 がある。切って使えば随分お得。

    http://iteadstudio.com/store/index.php?main_page=product_info&products_id=117
    2.54mm 40Pin Female Header (5 Psc) $1.50

    ー どうもなんでも 5 個 $1.50 のようだ。原価はずっと安く管理費用のほうが支配的なのか?

    ところで、電源切り替えの スライドスイッチは、どうしよう。4.3mm の高さに抑えるか、

    http://akizukidenshi.com/catalog/g/gP-01665/
    超小型スライドスイッチ IS−1250
    http://akizukidenshi.com/catalog/g/gP-02627/
    超小型スライドスイッチ 2回路2接点 IS−2235

    を付けることにして、上部の ノブ(?) を切る? 本体は 3.5mm 高だから 一応収まる。

    http://akizukidenshi.com/catalog/g/gP-03006/
    リセット用のタクトスイッチは、やっぱりこれ? いままでと同じように、ファームウェア書き換え専用。

    これに LED も 付ける。... と入らないおそれが... 裏に mega32u4 を付けることになるかも知れない。

    コネクタは、自分自身の ISP と シリアルは出したい。できれば、ISP も SPI に転用可能にしておきたい。

    シリアルは、TXD/RXD に XCK(or CTS) に加えて DTR(ピン未定) 。ISP は、ジャンパで RESET/SS 切り替え。SparkFun FTDI Basic Breakout と同じ配列にして 1x6。-- DTR/RXD/TXD/VCC/CTS=XCK/GND 。こうしておくと、シリアルも SPI として使える。

名称について

    なにを作るのでも名前を考えないといけない。ファイル名もあるし、最初に必要で、これが超やっかい。

    しょうがないので、なにか考えるのだが、O-duno (小角)にした。i がないが、まぁいいや。

    意味は、『小さい Arduino のつもりだが何か足りない』とでもしておこう。



    超ラフなレイアウト。以前作ったボード をもとにして作った。2.54mm ピッチ 1x14 でも 悪くないかも。だが、高さがあるから実際につけると不恰好になるかも知れない。

    それはともかく、主要部品は表に置けそうだ。だが、水晶や CR は、裏になりそう。

    あと、ISP を SPI として使うためのジャンパ -- 3穴 2.54mm は厳しいかも。

    http://akizukidenshi.com/catalog/g/gP-02736/
    小型スライドスイッチ 1回路2接点 SS12D01G4

    とかを使えるようにしておきたいところなのだが... ううむ。

    そういえば、
    http://akizukidenshi.com/catalog/g/gP-03908/
    2mmピッチジャンパーピン

    なんてのも買えるようになった。これで済ますか。リセット を接続するかしないかなら 2穴で済むし。



    すこしまともにしたレイアウト。コネクタの部品を作り予定の位置に置いた。あと 2mm ピッチのジャンパを作り基板外に置いた。

    リセットボタンの位置がわるい。押しやすいところに置くべき。



    とりあえずこうしてみた。電源切り替えスイッチの収まりガ悪い。
    2mm ピッチと 2.54mm ピッチの関係を分かるようにした。



    スイッチを
    http://akizukidenshi.com/catalog/g/gP-02736/
    小型スライドスイッチ 1回路2接点 SS12D01G4

    に変更。
    あと、ピン名をコメントとして入れた。
    ISP/SPI 切り替えを 2mmピッチジャンパーピンでできるようにした。
    HWB を ジャンパーしたときだけ Enable にしようかと思う。

      HWB ピンは HI-Z 入力なので、確実に Disable にしたければ、弱いプルアップが必要。ジャンパで Enable にするには強いプルダウンか接地にする。

      以前 LED をつないだら 明るいところでは Disable / 暗いところで Enable になったりした。それはそれで興味深いが実用的ではない。



    かなりのところまで配線完了。

    ISP/SPI, シリアルのコネクタは 180°回転した。こっちのほうがうまく配線できる気がする。

    ただ、このまま進めて良いものかどうか? XBee のピン配置をベースにするとあんまり美しくないのだ。CTS が反対側に行くのがちょっと困る。

    というわけで、CTS も (チップの機能を使わない) PORT にして、画像の下側は PORTD メイン、上側左は ADC(PORTF) メイン、上側右は SPI(PORTB) という風になった。



    完成。2mm のみのボードを想定して、リセットの位置を内側にした。あと、シルクの作成。
    Serial の DTR は、PD4 にした。

      Digital 側
      1 VCC
      2 RX PD2
      3 TX PD3
      4 () PB7(RTS)
      5 SDL PD0
      6 SDA PD1
      7 () PD4
      8 GND
      9 () PD5(XCK/CTS)
      10 () PD6
      11 () PD7
      12 3V3
      13 5V
      14 RST

      Analog 側(#14 から)
      14 () N.C.
      13 () PE6
      12 () PF0(ADC0)
      11 () PF1(ADC1)
      10 () PF4(ADC4)
      9 AREF AREF
      8 () PF5(ADC5)
      7 () PF6(ADC6)
      6 () PF7(ADC7)
      以下 SPI
      5 () PB3(MISO)
      4 () PB1(SCLK)
      3 () PB2(MOSI)
      2 () PB0(SS)
      1 GND

      Serial
      1 DTR PD4
      2 RXD PD2(RXD)
      3 TXD PD3(TXD)
      4 VCC
      5 XCK PD5(XCK/CTS)
      6 GND

      ISP/SPI
      MOSI 1 6 VCC
      SCK 2 5 MISO
      RST/SS 3 4 GND

      (V 1.0 t1 -- 間違い)
      MOSI 1 2 SCK
      RST/SS 3 4 GND
      MISO 5 6 VCC

      LED
      PC6 Red/Orange
      PC7 Green/Yellow

      HWB ジャンパ。ショートで HWB有効。
      ISP/SPI ジャンパ。1-2 で ISP, 2-3 で SPI

      未割り当てのピン PB4/PB5/PB6 PE2(HWB 専用)


  • oduno-1.0.zip (eagle データ)
  • oduno-1.0-out.zip (http://iteadstudio.com 提出用)

    今回は、iteadstudio.com で作ってみよう。5cm x 5cm 10枚で $9.9 なのは同じで送料は $4.0 。
    ルールは、前の Fusion PCB と同じような感じ。ファイル名どうとかは、ないようだ。

    あんまりチェックしていないのだが、前に作ったものを元にしているし、ひどいことにはならないだろう。

  • 来たメールに リプライするのではなく pcbあっとiteadstudio.com に送るらしい。即効で怒られた。

  • ISP のピン配置を間違えた。ピンヘッダの番号で割り当ててしまった。作り直さないと。

  • oduno-1.0a.zip (eagle データ)
  • oduno-0.1a-out.zip (http://iteadstudio.com 提出用)
  • oduno-01a.png (イメージ)

    一応作り直した。が、自信がなくなってきた。『データを差し替えてくれ』とメールは送ったが、受け付けてくれるかどうかは分からない。まぁ、ピンの間違いだから動作自体には支障ない。他にもっと重要な問題があるかも知れないし、まぁいいや。

      もう 作り始めているからダメといわれた。まぁしかたない。

    ところで、タカチのケースに SW53 というのがある。厚みが 11mm しかないので、見栄えがする。( 蓋を止める枠 を除いた)内寸は、 (たぶん) 49.4mm x 32.4mm 。うまくすると Foca や O-duno が入るかも。(といっても ピンフレームをどうするか別途検討する必要あり)
posted by すz at 23:51| Comment(0) | TrackBack(0) | 日記

2011年09月29日

PS/2キーボード関係のメモ

PS/2→USB変換器を6製品試す』 の記事を読んだ。結論としては、気に入る『PS/2→USB変換器』はなかったとのこと。

これぐらいなら、電子工作で作れそうな気がする。市販品で気に入らないなら 気に入るような仕様で作れば良いから、実用として役に立つものになるかも知れない。

 − 電子工作を趣味としていても、実用として役に立つようなネタは少ないのでメモしておこう。

そういえば、私の愛用キーボードは、PS/2 の HHK lite2 でインターフェイスは PS/2 だ。そして KVM につなげている。で、PFU の サイトをみてみると ... HHK lite2 は、USB のみになっている。

http://www.pfu.fujitsu.com/hhkeyboard/lite2/

まぁ、USB でも困らないのだが、KVM を活かしたいなら 『USB→PS/2変換器』 が欲しくなる。これは、電子工作で作れるのだろうか?

どうせなら、USB→USB で自由にキーマッピングを変えられるものとかも良いかも知れない。

... そういえば PS/2 マウスのほうが絶滅しかかっている。マウスも対応したほうが良さそう。


こういう前提で構想を練ってみよう。

チップの選定

    これは、文句なしに ATmega32u2 。いままで作ったライブラリがある。ただ、HID(HumanInterfaceDevice) はサポートしていないから、そこから作る。公開されているものだと LUFA を使うのも良い。あと USB の D+/D- を PS/2 として使えるような 機能も持っているので、変換アダプタが使えそうなのが良い。(ATmega32u4 も良いのだが、この機能は持っていない)

    これで、HOST との接続はできる。あとは、デバイス側。PS/2 マスタ は、XCK を使った同期シリアルでいけそう。ただしオープンコレクタ出力でないといけないので、外部デバイスがいる。 ちなみに ATmega32u2 は、5V での動作が可能で レベル変換で苦労することはない。

      D+/D- を PS/2 として使う場合、VCC でプルアップされ 特殊なポートとして駆動が可能になるようだ。... PS/2 は 5V だから VCC も 5V でないといけない。

    問題は、USB HOST 。Low スピード 1.5Mbps での 送受信を Port を使って制御する。V-USB など Device でも制御できるのだから HOST も原理的には可能なのだろう。ただ、電圧の問題がある。

    VCC が 5V ということは、PORT も 5V 。... となると 例によってツェナーダイオードのお世話になるしかないのだろうか? ... しょうがないのでとりあえずその方針にしよう。

    OTG 機能を持った マイクロコントローラなら、HOST にできるが ... どちらの変換機にするか最初に決めないといけない。USB→USB も無理。ものづくりとしては、こちらのほうが面白いはず。

信号線の割り当て

    D+/D- USB なのは当然だが、PS/2 の場合どちらを ( CLOCK信号/DATA信号 にするのか決められない。アダプタが 2通りあるはず。) 自動で判別できれば良いのだが、そううまくいくのだろうか?

    PS/2 デバイス側

      TXD(PD3) は、NPN Tr か Nch Mos FET で DATA信号を駆動。RXD(PD2) は、DATA信号 に抵抗を通して接続。
      同じように XCK(PD5) をCLOCK信号駆動用にして、別の PORT(PD4) を読み込みように割り当てる。

      あ、USART を使うと TX/XCK の極性 が逆になってしまう。インバータが必要。

    USB HOST (デバイス側)

      D+ に INT0 を割り当てたほうが良さそうなので、 PD0 を割り当てる。D- は PD1 。

      ソフトだけで PS/2 マスタを制御するのなら、逆変換のアダプタで PS/2 キーボードを接続することは、可能。その場合外付け の回路もいらない。問題は間に合うかどうか。割り込みを使わないなら、あるいはいけるかも。ちなみに 処理できないときは、CLOCK を L にしておけば良いらしい。

    HWB(PD7) FW 書き換え用。

      忘れてはいけない。あと LED とかも欲しい。

      ちなみに、5V で動かすので、UVCC/VCC/AVCC は VBUS (5V) に直結。

開発関係のメモ

    デバッグする環境は頭がいたい。

    まず、PS/2 キーボードやマウス を接続する方。PS/2 キーボードやマウス 自体の入手が難しい。まさか現役のキーボードで最初のテストをするわけにもいかないし。また、日本語キーボードは何通りかあって、くせがあったはず。PS/2 マウスは安いのを見付けたら買っておくのも良いかも知れない。

    次に HOST とのインターフェイス。PC しかない が、電源投入時にしか認識されない。また、最初のテストで PC を使うのは PC を壊すおそれがあり避けたい。


    http://www.dealextreme.com/p/slim-usb-2-0-to-ps-2-adapter-dongle-1440
    Slim USB 2.0 to PS/2 Adapter Dongle $2.58


    http://www.goodluckbuy.com/slim-usb-2-0-to-ps-2-adapter-dongle-1.html
    Slim USB 2.0 to PS/2 Adapter Dongle $2.64 (www.goodluckbuy.com)

    本末転倒にも思えるが、最初は、安物の『PS/2→USB変換器』を通してテストするのが良いのかも。起動後挿せば良いし、PCを壊すおそれも小さい。おかしくなったら抜けば良い。ただ、おそらく USキーボード専用で、(ちゃんとした)日本語キーボードのテストは無理だろう。

      だいたい PS/2 キーボードが US か日本語か 自動判別はできない。一方 USB キーボードは どちらか分かる(分かっていないといけない)はず。(自信なし)

      これらの種別の設定や キーマップの変更というのはサポートしたい。データは EEPROM に置くとして... 設定は、ツールなしで出来ると良さそう。アイディアとしては、NotePad を開いておいて メニューをキーコードの列を出力することで表示するとか...


    あとの問題は、ソフトの開発環境。別に ターゲットデバイスを用意する必要はない。ATmega32u2 ボードは既にある。( Teensy(1.0)互換ボード は今遊んでいる。)

    これだけで、まずは HID の開発ができる。その後は、2 pin だけで PS/2 デバイスを 制御してみる。PS/2 コネクタは持ってないし、ソフト USB 用として回路を組んで 逆変換アダプタで PS/2 キーボードやマウスをつないでみる。うまくいけば、まずは『PS/2→USB変換器』まで作れる。

    あと、USB に 変換アダプタを付けて PS/2 デバイスのテストはできる。PS/2 キーボードやマウスをつないで 『PS/2→PS/2』のテストもできそうだ。

    あとは、USB HOST のテスト。16 MHz という変則クロックだから V-USB をベースになんとかできるかやってみる。その前にツェナーを用意しないと。

PS/2 関係の製品について

構想2

    さて、ここまで読んでも、なにがしたいのかイメージできないと思う。
    どういう要素が使えるか、洗い出しただけに近いからイメージできないのも当然かも知れない。

    少しまとめてみることにする。

    1) 1:1 の変換

  • ATmega32U2 を使って USB or PS/2 - USB or PS/2 変換をするボードを作る。

  • ボード自体は、USB miniB - USB A メス のコネクタを付ける。

  • PS/2 に接続する場合は、USB - PS/2 , PS/2 - USB の変換コネクタを使う。

  • CPU は、5V 16 MHz で動作させる。-- UVCC/VCC/AVCC は VBUS (5V) に直結。

  • USB miniB の方は、普通に USB として配線する。

  • USB A メスの配線は、D+ = PD0/D- = PD1 。75 Ωぐらいの抵抗を通して接続し、3.3V の ツェナーダイオードで 電圧の制限をかける。

      PS/2 に変換するときは、3.3V までしか電圧が上がらない。が、たぶん大丈夫だろう。
      問題が起きるなら、ツェナーダイオードと GND の間に Nch MOSFET を入れたりすれば、良さそうではある。

      ツェナーダイオード の入手について :

      千石で リード部品 3.5〜3.7V or 3.2〜3.4V (リード部品 φ2.0 x 4.2mm) を扱っている。
      10 個 210 / 100個 630円。

      チップ部品なら、鈴商 とか。

      デジキーだと MM3Z3V3BCTあたり?

    このボードを使って、USB device, PS/2 device, USB HOST , PS/2 HOST のコードを作り別々にテストする。それが出来たら、実際の 『PS/2→USB変換器』や 『USB→PS/2変換器』 を作ってみる。PS/2 といっても キーボードとマウスは別のプロトコルだから、それぞれ別のものとしてファームウェアを作る。

    できたら、自動判別したいのだが、うまくいくかどうか分からない。最悪別々のファームウェアになる。また、『USB→USB変換器』や 『PS/2→PS/2変換器』も 対応できるようにしておきたい。

      ちなみに、『USB→PS/2変換器』は、ATmega32u2 っである必要はない。ATmega328p とかで十分。
      USB device を V-USB で作るのは無理(割り込み禁止で動作させたり出来ないため)


    2) 2:2 の変換

    次の段階では、キーボード、マウスを両方扱えるものを検討してみる。といっても 最初から考慮して設計しておかないと、ほとんど再設計になりそうだ。

参考資料
http://www.oadg.or.jp/ 『OADGテクニカル・リファレンス ハードウエア編』
http://ioiodesu.web.fc2.com/PS2/PS2.HTML PS/2 『マウス/キーボード プロトコルとインターフェース』

http://www.usb.org/developers/hidpage/
http://www2d.biglobe.ne.jp/~msyk/keyboard/layout/usbkeycode.html 『USBキーボードのキーコード』

追記: PS/2 コネクタ(メス)
posted by すz at 23:35| Comment(2) | TrackBack(0) | 日記

2011年08月21日

スナップドーム

以前 DealExtreme で買った 小型 Bluetooth キーボード を分解してみた。

写真(準備中)

このキーボードは、基板の上に メタルスナップドームと言われる ばねを置いて その上からフィルムを貼りつけてある。キートップは、ラバーで下向きにポッチが付いていて メタルスナップドームの中央を押すようになっている。金属製の枠で、ラバーを押さえるしくみ。

    フィルムは、単なる幅広のテープのようにも見える。ひょっとしたら PP のガムテープで済ませられるのかも。

これを見て、これなら 薄型の小型キーボードを自作可能では?と思ってしまった。

まず、メタルスナップドームだが、オムロンからも正規のパーツとして出ている。

デジキーだと これ

50 個 1082円、100 個 1947 円だそうだ。ちなみに データシートには、基板のパターンの作り方の説明があった。

他も探してみると ... なんと バネ屋さんが扱っていた。確かに スイッチのバネのみだから 扱っていても不思議はない。

例えば 『SWドームスプリング 』の ページで扱っている。ちょっと高い (100個 4000円) が、色々なサイズがある。

このメタルスナップドームは、タクトスイッチにも使われている。... 秋月の 『タクトスイッチ 100個セット』(700円) を分解して取り出すのが、もっとも安価に入手できる方法かも知れない。

    分解するのは、簡単で 上部の金属の枠をニッパで取れば良い。中に メタルスナップドームが入っている。-- ただ、ポッチが付いていない。うまく接触させる工夫が必要かも。

    ひょっとして、スルーホールのユニバーサル基板で簡単に実験できるかも。下側で配線して テープで貼るだけ -- これでうまくいくようなら、本格的なものを検討しても良いかも知れない。本格的なものといっても、とりあえず テスト用として 5cm x 5cm 以内の パターンを起こして Fusion PCB に発注してみるとか。

さて、これでキーボード(の基板部分)を作ったとして ... 4mm/5mm ぐらいの小径の メタルスナップドームだと 中央を的確に押す必要があり、キートップがないと実用としては使いづらい。

キートップはさすがに自作できないと思うが、ひょっとしたら既製品のキーボードを分解したら使えるものがあるかも知れない。

    確か ノートPC のパンタグラフ方式のキーボードはプラスチックのパーツが薄い メタルにつめで取り付けられていたはず。で、下にシートがあってそれを押すしくみ。うまくすれば使えるかも。

    ただそれを上手く使って作れたとして、気に入るものが作れるのかどうか?

    ゲーム・コンソールの補修パーツには、ボタンがある。スナップドームを使って、このボタンで押すようなものは作れるか。クリック感がある妙なボタンになるが、それも良いかも。それを作るかどうかは、別にしてこういうのを知っておくと応用が効く場合もあるかも知れない。

    あと BlackBerry のガワとかも売っている。キーボードの部分は、たしかプラスチックの部分のみで押すことはできる。このガワを利用したボードとかを作れるかも知れない。

追記 2011/09/22:

Mini Dip Momentary Tactile Button Switch 50-Pack 12x12x5mm $5.56 (goodluckybuy.com)

というのを見つけた。大きな スナップドームが入っていることを期待して、ちょっと買ってみることに。

他に
posted by すz at 15:00| Comment(0) | TrackBack(0) | 日記

2011年07月02日

FPGAライタの設計(3)

もはや FPGAライタというのは適切ではないのだが、前タイトルを継承して続ける。

いままでの経緯

    ARTEMIS ボードを設計し、その上で動かすなにか.. を考えて AVR互換コアを設計してきた。AVR互換コアは出来上がったのだが、ARTEMIS ボードの JTAG インターフェイスは特殊で それを扱うツールもまた作らなくてはならない。

    それは想定内だったのだが、『MachXO 2280 Breakout ボード』 を最初のターゲットに変更したので、サポートする内容が随分増えた。

      MachXO 2280 Breakout ボード』は、安価なだけでなく、安易に使える。rtavr のリファレンス・ボードとして使えると思ったのが変更した理由。

      ボードもツールも信用できない状況でデバッグするのは、苦痛なので 確実に動作するボードが欲しかったのだ。

      ここで、Xilinx を選ばないというのには理由がある。MachXO2 に興味が出てきたので、将来サポートしたいと思っていた。幅広いデバイスに対応できるようにツールを設計する必要が出てきたので、最初から タイプの違う 2 種類のデバイスをサポートして 後々困らないようにするのが、狙い。

    さて、最低限必要な機能は以下のもの

    • (AE-UM232R の) BitBang で Spartan-3/6 に Config できる。
    • BitBang を使った JTAG通信で(Spartan-3/6 に接続された )SPI_FLASH に書き込める。
    • BitBang を使った JTAG通信で rtavr のデバッグができる。(ISP と シリアルのような通信)

    Config できることは、ARTEMIS ボードのみ必須。JTAG通信で 設計した回路と通信できることが重要で、それはターゲットが変わっても変わらない。

    あと、いろいろなファイルをいろいろな方法で 送り込む必要がある。(Config と SPI_FLASH と ISP) この操作方法は統一感があるようにしたい。

現状

  • rtavr_tools-0.2.tar.gz

    これが今できているものの一式

  • 設定ファイルの読み込み
  • ft245r/ft232r の BitBang Cable ドライバ (FT2232H 対応)
  • SVF ファイルで使うような JTAG 操作のプリミティブ
  • MachXO 2280 の IDCODE の確認と JTAG通信への移行
  • テスト用 HDL (同梱) との JTAG通信

    これが今確認できたことのすべて。

    動作確認できていないが、ツールを作るたみに必要なパーツのかなりの部分は作成済み。

今後の作業

    ここからが本題。

    これから、作ったパーツをくみ上げていく予定なのだが、どのようにくみ上げるかが悩ましい。この記事で整理しておこうと思う。

    ずっと悩んでいたが、avrdude と良く似た インターフェイスにするのが良さそうという結論。avrdude をコマンドラインで使うことが多いので、似て非なるオプションにすると混乱しそうだ。

    必須のコマンドライン・パラメータ。


    -c CABLE名
    -P CABLE の PORT 名
    -B bit clock
    -b baud
    -i テイテンシ パラメータ

    -p TARGET FPGA名


    自分の Bitbang ライタのコードをベースにしているし、CABLE のパラメータはこんな感じで良いだろう。あと FPGA名 も指定しないと。

    このあたりは、最初にパラメータとして指定しないと、認識ができない。

    CABLE名 や FPGA名 は、設定ファイルに記述する。どのように記述するかはきっちりとは決まっていない。また、なんでもかんでも設定できるわけではない。コードを作る都合で、外にだすだけ。例えば、FPGA の IDCODE は、設定ファイルに記述するが、サポートできる Family はハードコーディング。Lattice の場合、知っている IDCODE しかサポートできないし、Xilinx でも 知っているもの以外は受け入れないようにする。

    さて、必須以外のパラメータは動作を指定するもの。... なのだが当面決めないでおこうと思う。

    どうするか..というと コマンドモードを作り そのモードに入って操作する。

    最終的には、動作を指定するパラメータは コマンドモードでのコマンドに変換しようと考えている。

    最初に作るのは、spi terminal モード。

      コマンドラインモードから さらに terminal モードに入る。テスト用のHDL を使うと 入力した文字がエコーバックされる。

      ここから抜けるのは、~. か +++ をすばやく入力。... というのが今のコード。操作できないかも知れないので、動かして詰めていく。



付録: JTAG の API


    void jtag_go(CABLE cbl,int state);
    void jtag_init(CABLE cbl);
    void jtag_reset(CABLE cbl);
    void jtag_IDLE(CABLE cbl, int ms, int count);
    void jtag_SIR(CABLE cbl, uint8_t *buf, int bit_len, int flags, uint8_t *rcv_buf)
    ;
    void jtag_SDR(CABLE cbl, uint8_t *buf, int bit_len, int flags, uint8_t *rcv_buf)
    ;

    void jtag_SIR32(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv_
    data);
    void jtag_SDR32(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv_
    data);
    void jtag_SDR32R(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv
    _data);

    32bit までなら コードが書きやすく分かりやすいように tag_SDR32 などを作っている。jtag_SDR32R は、SPI 通信用で MSB first 。

    flags は、1 : 受信も行う。2: 状態を移行しない。(最後の TMS==0)。

    いまのところ、API 間で非同期にI/O はしていない。受信をしない jtag_SDR を連続で call するような場合しか有効でないが、jtag_SDR を 1 つにまとめたほうが最適化になる。要するに非同期してわずかに高速化してもあまり意味はない。

rtavr_tools-0.3.tar.gz

    少し前進。コマンドモードを作り、コマンドのテストに入っている。

    cmd mode usage:
    (fl|file_load) [filetype] file
    filetype: bit jed mcs mem
    (tl|target_load) memtype [size]
    memtype: fpga_ram fpga_flash spi_flash rtavr_isp
    ram flash spi isp
    (d|dump) [addr size flags] [! outfile]
    flags: 1 reverse bit (in byte)
    (w|program) memtype
    (v|verify) memtype
    (t|terminal) [bitclock]
    (q|quit)

    こんなコマンド体系になった。

    fl file名 で 内部メモリバッファに読み込み、
    v flash で XO の flash と同じかチェックする。

    jed ファイルを使って flash の内容と一致することを確認できた。

    v ram は、RAM の内容をチェックするのだが、一致しないどころか、毎回違う。
    これは ... 今動いている回路の状態を読み取っているのだろうか?

    dump コマンドも動く。! を付けるとファイルに log することもできる。

    RAM を見たいときは、tl ram として、内部メモリバッファに読み込んでから dump 。

    terminal は全然だめだし、rtavr_isp もダメ。.. まぁボチボチ 完成させていこう。

    書き忘れたのだが、jtag_SDR の start bit 位置が 8bit アラインという制限になっている。これだととても具合が悪いことが分かったので、

    void jtag_SDR_EX(CABLE cbl, uint8_t *buf, int off, int bit_len, int flags, uint8
    _t *rcv_buf, int roff);

    というのを新設した。off/roff は 開始位置で bit 単位。これを実装するために CABLE のインターフェイスも変更。

    あと、xp2 用のコードも マージしつつ変更しているんだが、0.3 では最後にバグをいれてしまい、書いた通りには動かなくなっている。

rtavr_tools-0.4.tar.gz

    また少し前進。erase コマンドを作成して動作を確認。

    そして MachXO に対して flash に書き込めるようになった。ただし、ちょっとバグがあって USERCODE の 最下位バイトが書けない。

    cmd> e flash
    erase success
    cmd> w flash
    Programming :################################################## 29.278 sec
    Verifying :################################################## 12.660 sec
    program success
    user_id = 0x52543031
    user_id unmached 0x52543031 0x52543000
    cmd> v flash
    Reading :################################################## 12.644 sec
    verify error at 60822 0x31 != 0x00
    address_size 1116 data_width = 436
    cmd> v flash
    Reading :################################################## 12.761 sec
    verify error at 60822 0x31 != 0x00
    address_size 1116 data_width = 436
    cmd> e flash
    erase success
    cmd> w ram
    Programming :################################################## 23.747 sec
    Verifying : 0.034 sec
    program error
    user_id = 0x52543031
    cmd>

    実行したときのログ -- ram への書き込みは verify でエラー。

    flash への書き込みはされていない。エラーになったとき ISC_PROGRAM_DONE をしないようにしているが、その場合 書き込んだ内容が有効にならないことも確認できている。

    あと、ちょっと遅い。たぶん jtag_IDLE に時間がかかっているのだろう。そういえば、時間も合っていない。gettimeofday() 使うようにしないと。

    ちなみに、xp2 は持っていない。コードは書いておくが、テストは先の話。MachXO2 Pico Dev kit は入手済みでテストは出来るが、肝心のコードが出来ていない。(ちょっと難しいのだ)

    追記: DDT #1 FPGA超入門は、まだ入手可能なようだ。Amazon, マルツで買える。一応 押さえておくことにした。

関連記事
posted by すz at 15:25| Comment(0) | TrackBack(0) | artemis

2011年06月29日

MachXO 2280 Breakout ボード

デジキーで 2700円 と安価に購入できる FPGA ボード について。



簡単な説明

    FPGAは、Lattice 社の MachXO 2280 。-- MachXO2 が出ているから、最新のチップというわけではない。といっても 発表は最近で 2011/4 。価格は $29.9 ということになっている。

    このボードには、FT2232H が載っていて、非常に安易に使える。USB に接続するだけだ。Lattice 社の合成ツール Diamond (最新は v1.2)でもサポートしていて、ビルドしてから、2オペレーションで書き込みが可能。

      (1) Tools→Programmer を選ぶと ダイアログが出る。
      (2) (一回設定した後は) Download ボタンを押す。

    FPGA に接続されているデバイスは、(JTAG 以外には) LED x 8 のみ。

規模は小さめで、特にブロック RAM が少ないのが苦しいが、気軽に使えるのが気に入ったので、rtavr の最初のリファレンスボードとして使うことにした。

こうなるとは、当初は思ってもみなかった。

合成ツールは Diamond を使用している。Xilinx から入ったのだが、使いやすい印象。メジャーどころの Altera や より 合成ツールの サイズが小さい -- それでも大きいが -- というのは、試用するの場合の利点。

    rtavr を動かす本命は依然として 自作の Artemis ボードのつもり。だが、Artemis ボードを使う前にツールの開発が必要なのだ。ツールの開発を 『MachXO 2280 Breakout ボード』をつかってやることにした。そして、ツールが動けば勢いで rtavr も 先にテストしてしまうだろう。

  • 自作ボードでしか rtavr を動かせないというのでは、都合が悪い。完成しても誰も試そうとはしないかも知れない。またバグが報告されても、共通のボードでないと確認できないかも知れない。そういう意味でリファレンスボードはあった方が良いのだ。

  • ツールでは、FT2232H を Bitbang モードで使う。こうすることで Artimis ボード の AE-UM232R とコードを共通化することができる。(ちなみに ツールは開発中だが、JTAG が使える所までは出来ている。)

  • 『MachXO2 Pico dev kit』(LCMXO2-1200ZE-P-EVN) も デジキーで買えるようになった。... が、4787 円と思ったより高い。このボードに興味がないわけではないが、今は組み込まれているデバイスを動かすような ことの優先度は低いし、リファレンスボードとしては使わないことにした。


入手先や資料について


コネクタの アサイン図:

MachXO 2280 Breakout Board Evaluation Kit(LCMXO2280C-B-EVN)

          TOP View

J10 J6 J5
(1) (2) (1) (2) (1) (2)
PB9B(P8 ) PB2A(P2) Lattice VCCIO GND PT2C(B2) PT9A(D8)
PB9A(P7 ) PB2B(P3) VCCIO GND PT2D(B3) PT9B(E8)
PB10E(N8 ) PB2C(N5) VCCIO GND PT3A(A2) PT9C(E9)
PB10C(P9 ) PB2D(N6) VCCIO GND PT3B(A3) PT10A(A10)
PB10D(P10) PB3A(T2) VCCIO GND PT3C(D3) PT10C(C9)
PB10A(M10) PB3B(T3) VCCIO GND PT3D(D4) PT10D(C10)
PB11C(R9 ) PB3C(R4) VCCIO GND PT4A(C4) PT10E(D9)
PB11D(R10) PB3D(R5) VCCIO GND PT4B(C5) PT10F(D10)
PB12A(T10) PB4A(P5) -- -- PT5A(D6) PT11A(B9)
PB12B(T11) PB4B(P6) -- -- PT5B(D5) PT11B(B10)
PB12C(N10) PB4C(T5) -- PT15A(E10) PT5C(B4) PT12A(A11)
PB12D(N11) PB4D(T4) -- PT15B(E11) PT5D(B5) PT12B(A12)
PB13A(R11) PB5A(R6) -- PT15C(B13) PT6E(E7) PT12C(B11)
PB13B(R12) PB5B(T6) -- PT15D(C13) PT6F(E6) PT12D(B12)
PB13C(P11) PB6A(T8) PT7C(A6) PT16A(B14) PT6C(A5) PT13C(C11)
PB13D(P12) PB6B(T7) PT7D(A7) PT16B(C14) PT6D(A4) PT13D(C12)
PB14A(T13) PB7C(M7) PT8C(B8) PT16C(A15) PT6A(C6) PT14A(A13)
PB14B(T12) PB7D(M8) PT8D(C8) PT16D(B15) PT6B(C7) PT14B(A14)
PB14C(R13) PB8C(R7) FTDI -- GND PT7A(B6) PT14C(D11)
-- PB8D(R8) Chip -- GND PT7B(B7) PT14D(D12)
(39) (40) (39) (40) (39) (40)
  (LED)
[D5] [D1]
PB15D(P14) PB16D(P16)
[D6] [D2]
PB15B(T15) PB16C(P15)
[D7] [D3]
PB15A(T14) PB16B(R16)
[D8] [D4]
PB14D(R14) PB16A(R15)

TP0 - TP10 : VCC10 (3V3)

J1 -- JTAG J9

(1) 3V3 (25) PD14D(R14) [D8]
(2) NC (27) PB15A(T14) [D7]
(3) NC (29) PB15B(T15) [D6]
(4) TCK --- R3 --- FT2232H ADBUS0 (31) PB15D(P14) [D5]
(5) TDI --- R4 --- FT2232H ADBUS1 (33) PB16A(R15) [D4]
(6) TDO --- R7 --- FT2232H ADBUS2 (35) PB16B(R16) [D3]
(7) TMS --- R9 --- FT2232H ADBUS3 (37) PB16C(P15) [D2]
(8) GND (39) PB16D(P16) [D1]

(R3,R4,R7,R9 = 70 ohm)


    20x2 の コネクタが 8 つ付けられるが、普通の使用方法で それを全部使うのはあまり考えられない。そこで、写真右サイドの 4 列(J6,J5)と 左サイド中央側の 2 列(J10)を 普段は使うようにしようと思う。そう考えて ピンアサイン図を作成した。

  • Lattice Diamond でのピンのアサインには、() 内の ピン番号を使用する。

  • 2x20 ピンソケット(低メス) を J10, J6,J5 に付けようと思う。

  • 実験用には、 C基板(旧: FR-4) を使うつもり。必要な信号の分だけ ピンヘッダを下向きに付ける。
    (注意) ピンヘッダを付け過ぎると 抜き差しが非常に難しくなるので注意

  • C基板(新: CEM-3) は穴が少ないので、横向き にしか付けられない。C基板(旧) だと 縦向きも可能。

  • J9 で基板をカットすると JTAG ケーブル として使えるかも知れないので、できるだけ J9 は使わないようにしようと思う。-- ちなみにカットしてしまうと、FPGA は再config できなくなる。FPGA を壊してしまったり、二度と使うつもりがない場合にしか カットするつもりはない。

  • ちなみに 上下のコネクタは、GND が多く 3V3電源 がない。信号線を引き出すような目的に合うと思う。実際に使う予定は今のところないが、拡張ボードを 作って 直付しようかと目論んではいる。

  • LED の信号は J9 (25) - (39) にも出ている。(位置は、左サイド 最外側の 下 8 pin)
    基板をカット する場合は、J9 の右側が良さそう。
    ここに ロジアナを接続すれば、波形を見ることが出来る。目測できないような信号でも LED に出力する意味はありそう。

      ロジアナで使うようにするには、JTAG の 8pin と LED の 8pin に 1列の ピンヘッダを付けるのが良さそう。


    いろいろ書いたのだが、とりあえずやりたいのは、水晶発振の実験ぐらい。
    デバッグのためになんらかの デバイスを付けるつもりはない。ツールでの通信が可能になれば不要になるはずなのだ。

    ちなみに、ツールでの通信は、まだうまく行っていない。そのデバッグのために ロジアナは必要になるかも知れない。

制約ファイル(.lpf)


      BLOCK RESETPATHS ;
      BLOCK ASYNCPATHS ;
      LOCATE COMP "LED_7" SITE "R14" ;
      LOCATE COMP "LED_6" SITE "T14" ;
      LOCATE COMP "LED_5" SITE "T15" ;
      LOCATE COMP "LED_4" SITE "P14" ;
      LOCATE COMP "LED_3" SITE "R15" ;
      LOCATE COMP "LED_2" SITE "R16" ;
      LOCATE COMP "LED_1" SITE "P15" ;
      LOCATE COMP "LED_0" SITE "P16" ;
      USERCODE ASCII "RT01" ;
      IOBUF PORT "LED_7" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_6" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_5" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_4" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_3" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_2" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_1" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_0" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;

    制約ファイル(.lpf)は、ピンの番号を書くらしい。PB16D とかではない。

    LED をドライブするだけなので、他の設定は適当。

      SLEWRATE は FAST と SLOW があり FAST がデフォルト。意味なく FAST にすることはないと思ったので、SLOW に変更。
      PULLMODE には、UP/DOWN/KEEPER がある。LED は L で点灯するだけなので、NONE にしておいた。
      LVCMOS25 と LVCMOS33 との違いが実際にあるのかどうかは、良く知らない。DRIVE 電流の値は、いくつかあるが、自由に選べるわけではないらしい。LVCMOS25 では 12mA が選択できたので、そのままにしてある。


rtavr_tools-0.1.tar.gz

    開発中のツール。test_hdl ディレクトリに テスト用の HDL コードを置いてある。これを書き込んで、src の basic_test をビルドして動かすと、テスト用の HDL コードと SPI で通信する。

      通信もちゃんと動いているわけではない。9 bit 送ると 8bit 受け取れるという変な状況。

      ... どうも FPGA 側で JTDI が ラッチされているような感じ。そういうものならば、8bit とか 16bit とか最低単位を書いたらいったん Shift-DR を抜けて入りなおすような、処理に統一した方が良さそうだ。いったん抜ければ CS がトグルされ bit 位置が リセットされる。

      rtavr の slave-SPI を使うような場合、2 バイト分を送りこむと AVR 側が間に合わないのでどうしようかと思っていたが、1 バイト書いたら CS トグルなら 余裕ができて好都合。

    作成中のコードは沢山あって、これから組み上げていく予定。

      ほとんどのコードはテストできていないが、

    • .bit(Xilinx) .mcs(Xilinx) , .jed(Lattice) , .mem(Verilog) のファイルの読み込み(パーザは いいかげん)
    • Lattice XO の Config, Xilinx の Config (作っただけ)
    • FT245R/232R BitBang Cable ドライバ(結構動いている)、serjtag Cable ドライバ(作っただけ)

      などが含まれている。

    一応かつて 雑誌の付録になったものはサポート可能にしたい。-- 結構持っているし。ただ Altera は 自分の NotePC に 合成ツールが入れられないし、チップ単体で買えない or 買いづらいのでパス。

    XP2 も チップが買えるし、サポートしたい。(DDT付録 はもっていないけど)

    ただ、無制限にチップをサポートするつもりはない。基本は、自分が使う予定があるもののみ。

MachXO 2280 について

    実は細かいことは知らないのだ。
  • Config 用 FLASH 内蔵
  • 4LUT x 2280 の規模
  • ブロックRAM は 8kbit x 3
  • 内蔵発信器と 2 つの PLL 。

    これぐらい。ブロックRAMの容量が少ないので、チップ自体には興味がない。ボードが入門用に最適だったので選んだだけ。

    Config のしかたは、SVF ファイルを読んでだいぶ理解した。XP2 とおなじようなやり方(違いはある) 。一方 MachXO2 の Config のしかたは、だいぶ違う。あと、FLASH と RAM でデータ形式が違う。.. ちょっと ツールで対応するのは面倒。

    MachXO2 には興味があるが、-1200 は 、規模が小さくブロックRAMの容量も少ない。いま Lattice の チップを買うとすれば(実際は買わないが) LFXP2-5E/8E が良さそうな感じ。

MachXO 2280 Breakout ボードの利用案

    JTAG を通して PC と通信できれば、結構応用範囲が広がる。BitBang では、最大でも 3.7Mbps 程度の帯域にしかならないが、MPSSE を使って通信すれば、24Mbps (3MB/sec の 同時入出力) が可能だ。4pin しか接続されていないから、FT2232H の他の機能は使えないのが残念ではあるが、この程度までなら、お手軽に使える。

    USB なので、うまくバッファリングしてやらないと 途切れなく データを送受信するのは難しいかも知れないが、ブロックRAM もバッファに使うなどしてやれば、サウンドデータを送受信することも可能かも知れない。

    あと、いろんなデバイスとの通信テストとか。ピンが沢山あるから、付ける一方にして、外さないという使い方が可能。PC で制御プログラムを作って確認後、ターゲットのマイコンに移植するやりかたもできる。

    月並みだが、ロジアナ系。低速で良いなら メモリとかなしで作れるだろう。その場合 PC のディスクに全部ログするような使い方もできる。FT2232H を生で使っても似たようなことはできそうだが、FPGA で作るメリットは柔軟性。高速だが 2bit のみとか、低速だが100bit みたいなことができる。

    メモリを付けてまで作るようなことは考えない。手間を考えれば メモリ付きのFPGA ボードにしたほうがお手軽そうだ。

    あと、いろんなライタに仕立てるのは可能。 通信ができる以上、工夫次第で JTAG すら可能だろう。

rtavr_tools-0.2.tar.gz


    spi_test -- spi_echo test1
    30 ff (7f)
    31 30 (18)
    32 31 (18)
    33 32 (19)
    34 33 (19)
    5535 3455 (1a2a)
    aa5536 35aa55 (1ad52a)
    37 36 (1b)
    38 37 (1b)
    39 38 (1c)
    ff 39 (1c)
    ff ff (7f)
    spi_test done

    ようやく通信できた。左から PC の出力データ (MSB first) 、PC への入力データ。() は参考用で 1bit 右シフトした値。8 bit のシフトレジスタがあるだけなので、1 バイト分後で出力されている。

    ググって見付けた 『よくわかるバウンダリスキャン試験解説講座』を読んで TCK の立ち上がりで シフトすることを理解した。SPI とは極性が逆だ。

    test_hdl も直してようやく動いた。

    これで JTAG の API も FIX 。

    void jtag_go(CABLE cbl,int state);
    void jtag_init(CABLE cbl);
    void jtag_reset(CABLE cbl);
    void jtag_IDLE(CABLE cbl, int ms, int count);
    void jtag_SIR(CABLE cbl, uint8_t *buf, int bit_len, int flags, uint8_t *rcv_buf)
    ;
    void jtag_SDR(CABLE cbl, uint8_t *buf, int bit_len, int flags, uint8_t *rcv_buf)
    ;

    void jtag_SIR32(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv_
    data);
    void jtag_SDR32(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv_
    data);
    void jtag_SDR32R(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv
    _data);

    32bit までなら コードが書きやすく分かりやすいように tag_SDR32 などを作っている。jtag_SDR32R は、SPI 通信用で MSB first 。

    flags は、1 : 受信も行う。2: 状態を移行しない。(最後の TMS==0)。

    いまのところ、API 間で非同期にI/O はしていない。受信をしない jtag_SDR を連続で call するような場合しか有効でないが、jtag_SDR を 1 つにまとめたほうが最適化になる。要するに非同期してわずかに高速化してもあまり意味はない。

    そういえば、

    int (* get_tdo_bits)(CABLE cbl, int bit_len, int tdi, uint8_t *rcv_buf);

    なんて (CABLE の) API を作ったのだが、使っていない。これは不要だった。(削除予定)
posted by すz at 21:52| Comment(0) | TrackBack(0) | artemis

2011年06月19日

UM232H

FTDI のドキュメントを調べる機会があって、見ていたら FT232H という Hi-Speed(480Mbps) のチップが出ていることを知った。このチップを使ったボード UM232H も FTDI から出ている。(データシート)



    デジキーの価格は、UM232H が 1801円。

    FT232R の AE-UM232R と比べれば高いし、シリアルが 12Mbps で動いたところで、普通の使用方法ではメリットはないだろう。

    メリットがあるのは、MPSSE を使った JTAG や BitBang 使うようなものや、SYNC 245 FIFO/FT1248 を使った 高速パラレル通信。MPSSE を使った JTAG は、最大 30Mbps , SYNC 245 FIFO は 40 MB/sec と書いてある。

    FT232R 用 BitBang ライタ も そのままで動いて、速くなるんじゃないかと思う。

      ちょっと見込みが甘かった。値は設定できるが、平均 550kbps ぐらいしか出ていない。(8bit x 2(ON/OFF) x 往復 だからデータの 転送レートは 2.2 MB/sec = 17.6M bps) 。 Full-Speed の性能は超えているから 確かに Hi-Speed だが、ちょっとしょぼい結果だ。

      AN232B-03:D2XXDataThroughput を見ていたら 1回の Write サイズを 3968 の倍数にせよと書いてあった。すなおに 3968 バイトにしてみたら 平均 2.3 Mbps になった。これならまぁいいか。

      (追記) FT_SetUSBParameter で 16KB を指定し、1回の Write サイズを 3968 x 4 にしたところ 3.87 Mbps まで出た。MPSSE の 1/5 ぐらいの性能だが、FT232R/245R 用の コードで動くのが、作る立場でのメリット。おまけでここまで出るのなら不満はない。

    従来から FT2232H があるが チャネルは 1つになった代わりに、安くなった。-- チップ単体だと FT232HL (LQFP48) が 383円。FT232R と比較できる価格だ。

    • FT1248 というのは、新規の機能のようだ。FT2232H にはない。

    • VCCIO は、3.3V のみ。これは、FT2232H も同じなようだ。5V トレラントにはなっている。

    最近は、FPGA に興味がシフトしているので、気になっている。

    JTAG では特に高速な方が良い。またパラレル通信の帯域はかなり魅力的。これぐらいの性能で PC とやりとり出来て、電子工作で使えるインターフェイスは少ない。しかもパラレルだから FPGA で受けられる周波数になっている。

部品についてのメモ:

チップも安いから、基板を設計したくなる。LQFP48 は小さいから AE-UM232R のサイズに入れられそうだ。互換ボードとか作ったから、いろいろ流用できそうだ。

ただ、ピン互換にするメリットがあるのかどうか? MPSSE がメインなら、シリアルとして config しないことになる。+αの機能を入れるなら SYNC 245 FIFO か FT1248 ではないかと思う。そうなると ピンが足りない... ような?

SYNC 245 FIFO/FT1248 を使わないなら、JTAG 専用で 良いではないかと言う気もする。.. となると Sparkfun FTDI Basic Breakout (3.3V) みたいなデザインが良さそう。(ただしピン互換は無理。RTS が必要だが 6pin に入っていない。)

  • MI0603J600R

    チップフェライトビーズ。60Ω@100MHz 。いろんな USB 関係の回路図で VBUS から 電源を取る場合に チップフェライトビーズを通している。 このチップは、Lattice の USB JTAG (FT2232HL) の回路図でも使っていた。UM232H だと 3 つ使っている。(VBUS からの 入力, VPLL, VPHY) 。

    秋月に BLM18PG600SN1D (1608, 60Ω@100MHz, 25個100円) があるので、ここで買う必要はない。ついでに買うなら ... という感じ。

  • PGB1010603

    USB D+/D- は直結なのだが、これが GND との間に入っている。ESD 保護用だそうだ。FT2232H の回路図にはないから、推奨といったところか?

      Arduino UNO の回路図みてたら、これが入っていた。思ったより一般的なのか?

      ちなみに、GND との間ではなく、SLD との間。SLD と GND の間には、BLM21 という チップフェライトビーズが入っている。値は書いてない。

  • MCR10(12K)

    1% 誤差指定の 12KΩが必要。買い忘れないようにしないと。

  • 93LC56BT

    UM232H の回路図では、SOT-23-6 の 93LC56BT を使っている。

  • NX3225SA

    表面実装型の水晶で、秋月で扱っている FA238 (3225サイズ) に置き換えられるのは、これ ... なのか?

    12 MHz が欲しいが、95 円もする。秋月の FA238 は、16/20/25 MHz のみだし、仕方がないか。

    .. ただ、ハンダ付けで一番苦労するのは、いつもこの水晶。ちょっと悩む。

  • NX5032GA 2pin SMD で安いというと こういうやつ。 73 円だし特に安いわけではないが、ハンダ付けが楽そう。ラジアルタイプは安いが、安っぽい感じがして嫌。固定する方法も悩む。

UM232R

    UM232H があるなら、UM232R もあるのか? ... と思ったのだが、同然ながらあった。
    で、データシートを見てみたら AE-UM232R とピン配置が 同じだった。

    ちなみに、AE-UM245R も UM245R もある。こちらはピン配置が違う。UM245R は、UM232R のチップを載せ替えただけのようなピン配置で、AE-UM245R は、秋月オリジナル。

追記(2011/10/8): ストロベリー・リナックスの FT232H モジュール
posted by すz at 19:48| Comment(0) | TrackBack(0) | 日記

2011年06月04日

コンピューターウィルス作成罪?

MiAU から 「情報処理の高度化等に対処するための刑法等の一部を改正する法律案」について慎重審議を求める声明 が出ている。

ソフトウェアをリリースしている立場としてかなり気になる。

『コンピューターソフトウェアの重大なバグ(瑕疵)の放置が提供罪に該当する事態がある』とのことだが、いくつか疑問がある。

ソースコードしか提供していないものがあるのだが、これは そもそも、『コンピューターソフトウェア』に該当するのだろうか? ビルドしなければ、動作することはないし、ビルド環境の違いで動作しないような場合もある。ー要するに 動作するものと ソースコードは、1:1 に対応しない。ビルドすら不可能な場合だってある。

それに、ビルドするときに改変して 『トロイの木馬』を埋め込むようなことは可能で、それは提供されたソースコードをみても分からない。

ソースコードの提供には、責任がないとすると ビルドして提供する側に責任があることになる。まぁ 『トロイの木馬』のような話もあるし、たぶん一般的な認識ではないかと思う。

    そうはいっても、法律を制定する側の 一般的な認識とは限らない。いままでの例から考えても、信頼しきることはできない。

次の疑問はライセンス。ほとんどの オープンソースのソフトウェアは、『AS IS で提供するものだから、いかなる保証もないよ』と(ソースには)書いてある。そして、それを了承することが 使用できる条件になっている。ビルドして提供するとしても、『使用できる条件』なのだから、ライセンスとして添付しての提供になるのが普通である。

オープンソースのソフトウェアは、無償であることが多い。『なんらかの保証を求めた時点で使用権を剥奪する』というのは、さすがに法的にも有効だと思うのだが、実際のところどうなのだろう?

ちなみに、有償のソフトウェアも同じような条項が付くのが普通である。保証するためのコストが価格に込められてないならば、やはり法的に有効であろうと思える。

でもそうであれば、重大なバグ(瑕疵)の放置って何だということになる。

だいたい、PL法でも ソフトウェア単体は 法の対象になっていない。命がかかわるような重大な問題であっても 対象にはならないのである。それには、ちゃんとした理由があるはずだ。

    実はちゃんとは知らないのだが、次の理由だろうと思っている。

    ソフトウェア単体では、どのように動作するかそもそも定義できない。OS やら ハードウェアを含んだシステムとして 定義しないと 動作の定義は不可能で、そういうものは普通装置として認識される。

    (装置であれば、PL法の対象になる。)


まぁ、こういうわけでソフトウェアにたいして、責任を追求するのは無理がありそうな気がするわけだが、無理が通される可能性はある。

さて、次の疑問。放置って何?

私の認識では、バイナリが違えば別のソフトウェアである。

    というか、ライセンスが違えば バイナリが同じであっても別のソフトウェアと言えるかも知れない。が、ここでは そこまでは追求しない。

おなじソースコードから作成した A と B のバイナリがあったとする。そして A と B を作った人(団体)が違うとする。

A を作った人は A のみの責任を負う。B に対する責任を負ういわれはない。

    これは、常識として通用している。これを前提として オープンソースのビジネスが成り立っている。

おなじソースコードから作成しても別のソフトウェアであれば、改変したソースコードから作成したら当然別のソフトウェアであろう。

放置しないということは、別のソフトウェアを提供しなおすということで、コストがかかるということだ。装置することが許されていないとなると、別のソフトウェアの購入を強制することが出来るということであろうか?

たぶんそんなことは、ないのだろう。それはともかく、重大な問題があったソフトウェア と 置換されるべき 別のソフトウェア との関係はどのように定義されるのだろう?

    なんだが、グダグダな感じで終わらせてしまったので、補足。

    要するに、バイナリとなってリリースされるソフトウェアは、それで完結している。

    発禁にすることはできても、表現を変えて再提出せよと命令することは出来ないのではないか?

    そういう風にかんがえると、『重大なバグがあったらそのままの形で売り続けてはいけない。』ぐらいにしないといけないのではないか?

    『そのままの形』と書いたが、バグがあることを告知して、修正版があれば、それを入手する情報が添付されていれば良いのではないか? (リンク先が更新されるという前提で)リンク を貼っておくのでも良いかも知れない。

    有償のものは、そういう感じで良いと思うのだが、無償のものはそれでは困る。有償だと金銭の授受がある以上責任がある人(団体)がはっきりしている。無償だと、配布している人が存在しないかも知れない。あるいは、著作権が切れている状態かも知れない。あと、歴史的理由で実用としては配布していないかも知れない。

    無償だと免責だとか、ソースコードが添付されていれば、免責だとか。なにか配慮が欲しい。

    バグがあるという理由で、著作物を消滅させることにはなって欲しくないものだ。

こういうわけで、現時点では、具体的になにを意味するかわからないのだ。そうであれば、反対すろこともできない。私も慎重審議を求めることにしよう。

追記: 2011/06/17 本日 「ウイルス作成罪」(不正指令電磁的記録作成罪) が成立した。

毎日jpの記事 では、コンピューターウイルスを「意図に沿った動作をさせず、不正な指令を与える電磁的記録」などと定義。という説明になっている。誰もが『これはバグの定義では?』と思う内容だ。記者の無理解のためこういう説明になったのか? はたまた 本当なのか? 本当だとすれば、どうしてこうなったのだろう?

そもそも、コンピュータ・ウイルスとは、使用者の意思に関係なく 無限に感染していくようなもののことだ。コンピュータに依存している社会が危機にさらされるから、そういう性質のものを作ること自体が絶対悪である ... という風に私は理解している。

    無限に感染していく性質ならば、必ず自分自身をコピーする性質がある(実行形式の)プログラムのはずだ。それだけを問題にすれば良い。「記録を破壊した」とかは、別の犯罪だ。そういうプログラムをなんらかの方法で実行させれば良いわけで、コンピュータ・ウイルスでなくとも成り立つ。

    「記録を破壊するプログラム」をメールで大量に送ること ... これは犯罪だとは思うが、なんらかの形で騙して 損害を負わせるようなことだから 詐欺の類ではないのか?

    「記録を破壊するプログラム」が、自分自身を 勝手にメールで送る ような機能を合わせ持っていれば、これはコンピュータ・ウイルスだろう。

追記: 解説がいろいろ出てきた

    『無断で他人のコンピューターにおいて実行させる目的』で ウイルスを 「作成」「提供」「取得」「保管」すると 罪に問われる。そして、ここで言うウイルスは、バグがあるプログラムを含む定義。

    ということらしい。

    他人のコンピューターにおいて実行させるのに、普通は「無断」などあり得ない。騙されて実行してしまうのが普通。騙されて実行してしまうことも この法律に引っかかるのだろう。だが、「騙す目的での行為」 と 「作成、保管」とは 論理として つながらない。どのようにでも解釈されうるおそれがある。

      『無断で他人のコンピューターにおいて実行させる目的を持ったプログラム』の 「作成のみ」なら プログラムの動作で判断可能で、まだ理解できるのだが、そうは書いてない。まぁ「保管」が含まれると恐ろしいことになるから、そうは書けないのだろう。

      そういう理由もあって、このような表現をしているのだろうが、やってはいけないことの本質を捉えていないから、どのようにでも解釈される印象だ。

    本当に 「無断で実行させる」例として、OS の脆弱性をついてアタックをかけて 実行させる という手段がある。これを罪とするのは、正当だとは思うが、これだけが該当するような感じではない。そして、これは本当の意味のウイルスの特徴ではない。

    増殖するのがウイルスの特徴であって、「無断で実行させる」だけならば「増殖」しない。 「増殖するもの」に対して 軽い罪のように思われるし、「増殖しないもの」に対して 重い罪のような印象がある。なにより、解釈しだいというのが怖い。

「情報処理の高度化等に対処するための刑法等の一部を改正する法律」 を読んでみた。

    いまさらながら、条文を読んでみた。正直 リンクで紹介されないと読む気がしない。ようやくリンクを見かけたので、読むことにした。

      第百六十八条の二 正当な理由がないのに、人の電子計算機における実行の用に供する目的で、次に掲げる電磁的記録その他の記録を作成し、又は提供した者は、三年以下の懲役又は五十万円以下の罰金に処する。

      一 人が電子計算機を使用するに際してその意図に沿うべき動作をさせず、又はその意図に反する動作をさせるべき不正な指令を与える電磁的記録

      二 前号に掲げるもののほか、同号の不正な指令を記述した電磁的記録その他の記録

    「作成」「提供」に関しては、どうもこれだけらしい。

    すなおに読むと...『正当な理由がない』 のにバグのあるプログラムを作成したり配布したらダメとしか読めない。

      『正当な理由がない』 -- 『興味本位』ってのは、『正当な理由』にはならないのだろう。趣味でプログラムを作るのに、『正当な理由』などあるのだろうか?

      『人の電子計算機における実行の用に供する目的』-- 実行させる目的 って何だ? そもそも プログラムを 配布するのは、実行させる目的のはず。ソースコードは、そのままでは実行できないが、実行させる目的 であるとは言える。ソースコードだけだからと言って 安心できない。

      ところで、AVR は、人の電子計算機に入るのだろうか? 入らないと判断できる記述ではないから入りそうな気がする。

      (一) は、やはりバグの定義にしか読めない。

    「取得」「保管」も同様で、『正当な理由がない』 のにバグのあるプログラムを「取得」「保管」してはならないという風に読める。

    「無断で実行させる」とかは解釈のひとつに過ぎないわけか。『正当な理由』だけが拠り所という感じ。悪意をもってと判断されば、なんでも罪に問える 内容に読める。

    悪評が高い 「不正アクセス禁止法」 でも、条文自体はちゃんと書いてあるように読める。それでも、『ACCS裁判』では、判事が内容を読み違えたと私は思っている。これはもっとひどい。条文を読んでも、どういう理由で、どういう行為が罪になるのかサッパリ分からない。いったい司法は、なにを基準に判断するのだろう?

      「不正アクセス禁止法」では、アクセス制御機能 = 鍵と理解すると 整合がとれた内容になっている。
      目的は、鍵による秩序の維持を図ること。
      (一) は、他人の鍵をつかうな。
      (二) は、鍵 を ピッキングで 開けようとするな。
      そして、(三)は 鍵 を 壊すな。

      バックドアは、 鍵がない入口があることを意味する。本来なら (三) かどうかは議論にすらならないはず。

      (補足) これは、私の個人的主張を平易に説明したもので、正確さにかける。だが、このように捉えないと 矛盾が生じる。そこまで分析はしたのだが、説明は困難なのでそこまでは踏み込まない。
      "鍵" という概念を導入して、それを保護することで秩序を守る という目的ならば、バックドアをも保護する のは "鍵" の存在意味がなくなるということで 論理が成り立たない。... 細かく分析すると、もっと出てくるのだが、これぐらいの説明で止めておく。


では、どういう内容なら良かったのか?

    たぶん 2 つの概念に分かれるのではないか

    ひとつは、『感染させるためのしくみ』を実際に行使する目的をもって作成するようなこと。

      『感染させるためのしくみ』とは、『計算機の使用者を騙してプログラムを実行させる』あるいは、OS の脆弱性を突くようなことをして、『計算機の使用者に無断でプログラムを実行させる』ようなもの。

      ここでは、プログラムがなにかということは問わない。そんなことをするのは、プログラムがなんであれ悪なのだ。

      だいたいプログラムを差し替えることは容易であり、犯行の直前まで安全なプログラムを実行するようにしているかも知れない。

      (追記)こうは書いてみたものの、『計算機の使用者を騙してプログラムを実行させる』ものには、メールの文面や Web サイトのリンクが含まれる。あまりに容易に作成できるから条件を変えるか、条件を増やさないとまずい。といっても、詐欺のようなものだし、実際に実行したら罪を問うことを否定はしない。

      ところで、 Web サイトに フラッシュ や java ,スクリプトが 含まれていたらどういう扱いになるのだろう? ほとんどの場合『計算機の使用者は意図』しておらず『無断で』動いている。java などは、『計算機で動作』はするが、計算機のファイルにアクセスできないようになっていて 『人の計算機で動作』とは定義されないようにしないとダメなのではないか?

    もうひとつは、本来の意味のウィルスの作成。

      本来の意味のウィルスは増殖することを特徴とするから、かならず自分自身をコピーする機能を持っている。そして、『計算機の使用者に無断で』自分自身のコピーを実行する

      『計算機の使用者に無断で自分自身をコピーする機能をもった』もの を 実際に行使する目的をもって作成するようなこと。

      このようなプログラムが 上記の機能と組み合わさると 他の計算機にも感染して爆発的に増殖することになる。だからといって組み合わせたものだけを罪とする必要はない。これだけでも危険なのだ。

      また、これと 上記のものとは、違う技術になる。どちらかの作成を専門とする場合もありそうだ。

    表現は吟味しないといけないのだろうが、どういう特徴をもったものがどういう理由でダメなのかをはっきり書けば良いのではないのだろうか?

    あと、例外として『正当な理由がある』場合はのぞくとなっていれば良いのだろう。どういうのものがダメか判断できれば『正当な理由がある』かどうかも判断できる。そして、『正当な理由』はまれだということになっていれば良い。できたら 『正当な理由の例』も条文にちゃんと書くべきだろう。
posted by すz at 10:10| Comment(1) | TrackBack(0) | 日記

2011年06月02日

FPGAライタの設計(2)

AVR互換コア rtavr の SMP化 も一段落した。そろそろツールに着手しようかと思う。

    ちなみに、rtavr の最新版は、これ。ツールができるまで凍結。

  • rtavr-0.9.3.tar.gz

FPGAライタの設計』で少し検討したが、これからはそれの実装がメイン。

作ろうとしているのは、

  • 自作 ARTEMIS ボードの コンフィグ と SPI-FLASH への書き込みが同じ操作性でできる。
  • ARTEMIS ボードに rtavr を入れた場合 ISP でプログラムだけの書き換えもできる。
  • さらに rtavr と SPI で通信し printf デバッグができる。
  • JTAG インターフェイスは、ARTEMIS ボードと接続できる AE-UM232R(ft232r) と自作の『AE-UM232Rピン互換ボード』(mega32u2)
  • AE-UM232Rは、BitBang だが、AE-UM232Rピン互換ボードは自作の serjtag プロトコルを使う。

こういうもの。SPI-FLASH への書き込みは、一旦 FPGA を コンフィグ して行う。

    コンフィグするものは、JTAG と SPI-FLASH を直結したものになる予定だが、rtavr を動かして接続するものも作ってみたい。

それ以外に

  • エミュレータと結合して、rtavr 用プログラムのデバッグ環境にする。

    verilator を使うと、完全なデバッグ環境を作れるかも知れない。ちなみに、verilator は構文チェックとしてだけ使っても有用だそうだ。

というのもやるつもり。SPI-FLASH への書き込みの方が後回し。
さらに、

  • Lattice MachXO2

も視野にいれる。リファレンスには、『MachXO2 Pico Dev Kit』を予定。

... なんたる大風呂敷!という気がするが、どこまで出来るものなのか.. まぁやってみよう。

こういうツールはオープンソースのものを含めて多数あるわけだが、わざわざ作るのは、FT232R BitBang に対応したものがないし、serjtag に対応したものも当然ないため。avrdude でやったように ft232r/serjtag のドライバだけを作るのも手なのだが、上位レイヤでエミュレータを付けたりしたいので、ほとんど自分で作ることになる。

そもそも、したいのは rtavr を使うための環境作りであって、単にFPGAのコンフィグだけがしたいのではないから、既存のツールとは合わない。

参考にするものは、

このあたりがメイン。あと、『USB-Blasterもどきの製作』の DDT#1付録LaticceXP2-5E書き込みソフト も参考にさせてもらおうかと思っている。

いままでも xulaload は見ていて、わからなくなったら xilprg も合わせて見る -- みたいなことをしている。mcs ファイルと bitstreame ファイルの読み込みコードはそれで作成済み。

CABLE ドライバ

    前置きが長くなった。まずは、下位レイヤから設計を始めよう。

    serjtag/ft232r の avrdude 用ドライバは既に持っているわけだ。open/close まわりはほぼそのまま使う。だが、インターフェイスは大幅に変える。serjtag のプロトコルに近いものにして、ft232r の方を合わせる方針。

    方針はそれで良いとして... 機能の定義。単なる JTAG ならあまり悩まなくても良いのだが、付加機能がある。

    接続されている信号 を列挙すると

    FPGA um232r um162(mega32u2)

    TMS D7/RI PB0(SS)
    TCK D5/DSR PB1(SLCK)
    TDI D6/DCD PB2(MOSI)
    TDO D3/CTS PB3(MISO)

    M1 CB0 PD5
    M2 CB1 PD4
    PROG_B CB2 PC4
    INIT_B CB3 PD1

    DIN - (PD0)
    CCLK - (PC2)


    JTAG から Config するには、M2 = H , M1 = L としてから、PROG_B = H → L → H とする。INIT_B は、H になっているはずだが、エラーになると L になる。

    正確ではないかも知れないが、だいたいこんな感じの操作をする。
    DIN/CCLK は、Serial SLAVE モード(M = 111) での Config で使うもので、おまけ -- 後回し。

    MachXO2 には、PROGRAMN, INITN という端子があって、よく似た機能になっている。(M1/M2 相当は必要ない)

    こういったピンの割り当ては、設定ファイルで 定義できないと困りそうだ。ただ... あまり凝ったことはしたくない。それと、AE-UM232Rピン互換ボードの UM162 では、serjtag を使うが、こういうピンの定義がそもそもない。serjtag 自体拡張しないと。

    um232r.type = ft245r
    um232r.tms = 7 # D7/RI
    um232r.tck = 5 # D5/DSR
    um232r.tdi = 6 # D6/DCD
    um232r.tdo = 3 # D3/CTS

    um232r.init = 11 # CB3
    um232r.prog = 10 # CB2
    um232r.m2 = 9 # CB1
    um232r.m1 = 8 # CB0

    とりあえずこんな感じ。ルールは次のようにする。

    • um232r は CABLE 名 で定義可能
    • ft245r は CABLE ドライバの指定で、決まった名前。
    • # から後はコメントで 無視。
    • ピンの指定は、CABLE名.ピン名 = [~][0-9][0-9] で、~ は負論理を示す。あと、存在しないものは定義しない。

    この程度なら、ちょっとしたコードで解析できるだろう。
    ちなみに serjtag の定義はまた違うもの。tms/tck/tdi/tdo の割り当ては決まっている。init/prog/m2/m1 は GPIO 的につかうから似たような設定か。

    さて、CABLE ドライバの操作メソッドは、

    int setup_port(int tdi, int tms, int tck)

      TDI/TMS/TCK の値設定。

    注意) tck を 1 に設定すると、クロックの極性が逆になる。
    setup_port を呼ばないと 初期値は不定。

    int put_tdi_bits(uint8_t *buf, int bit_len, int flags , uint8_t *recv_buf)

     TDI にビット列を送り込む。

     flags には、受信データを記録する CABLE_RECIEVE と
     最後の TMS の状態を H にセットする CABLE_TMS_HIGH がある。

    ビットストリームは、1 バイトの中では、LSB first

    int put_tms_tdi_bits(uint8_t *buf, int bit_len, int flags , uint8_t *recv_buf)

     TDI/TMS の組の データ列を送り込む。

     flags には、受信データを記録する CABLE_RECIEVE がある。

    ビットストリームは、1 バイトの中では、LSB first 。送信データは、TDI TMS の順。

    int get_tdo_bits( int bit_len, int tdi, int tms, unsigned char *rcv_buf)

     TDI/TMS の状態を設定して (bit_len 分) TDO を読み取る。

    ビットストリームは、1 バイトの中では、LSB first 。

    int setup_gpio(int pin, int value)

      PROG/M1/M2 の設定。

    int get_gpio(int pin)

    INIT の読み取り

    これだけにする。これを使って JTAG のプリミティブを組んでいく。まずは、ここまでをやってみる。

verilator

    ツールは作成中だが、なにかと面倒。FT232R 版の枠組みは出来てきたが、それだけで 1000行近い。

    ツール作成に飽きると verilator が気になってくる。verilator は、Verilog のソースを C++ や SystemC に変換してくれるツール(コンパイラ)。Icarus Verilog のようなシミュレータと比べて 2 桁速いそうだ。

      Icarus Verilog の入出力をツールにつなげて、なんとか rtavr 自体のデバッグができないか考えていたのだが、これが使えるなら悩む必要もない。

    まずは、ちょいとビルド。古い MinGW 環境でも flex/bbison を入れるだけでビルドはできた。

    で、50A 用の rtavr を通してみる。

    ひとつにまとめた rtavr_50a.v を作り rom_data.mem と同じディレクトリに置いて、

    verilator --cc rtavr_50a.v

    とやってみると、やたら Waring が出る。

    %Warning-IMPLICIT: rtavr_50a.v:1833: Signal definition not found,

    ほとんどは、こんな感じのもので、sub module に対する bit 幅 1 のパラメータが定義されていないというものだった。文法上問題ないようだし、他のツールも Warning にならないからわざわざ対応するつもりはない。

      %Error: rtavr_50a.v:2739: Unsupported: Can't unroll generate for; condition not <= or <
      %Error: rtavr_50a.v:2739: For loop doesn't have genvar index, or is malformed
      %Error: rtavr_50a.v:2739: Unsupported: Can't unroll generate for; condition not <= or <
      %Error: rtavr_50a.v:2739: For loop doesn't have genvar index, or is malformed

    で、エラーはこれ。USART の UBRR のビット数制限で generate しているところ が引っかかるので UBRR_BITS を外す。あと port も generate 使っているから RTAVR_PORT_ESCALATION を定義することで generate しないようにする。


    %Error-BLKLOOPINIT: rtavr_50a.v:3853: Unsupported: Delayed assignment to array inside for loops (non-delayed is ok - see docs)

    次は、ram の 0 初期化 (initialize での for 文) GPR_INITCLR, SRAM_INITCLR を外すことで対応。

    そうしたら... なんか出来た。

    -rw-r--r-- 1 suz Administ 200421 Jun 4 12:12 obj_dir/Vrtavr_50a.cpp
    -rw-r--r-- 1 suz Administ 19935 Jun 4 12:12 obj_dir/Vrtavr_50a.h
    -rw-r--r-- 1 suz Administ 1521 Jun 4 12:12 obj_dir/Vrtavr_50a.mk
    -rw-r--r-- 1 suz Administ 617 Jun 4 12:12 obj_dir/Vrtavr_50a__Syms.cpp
    -rw-r--r-- 1 suz Administ 1023 Jun 4 12:12 obj_dir/Vrtavr_50a__Syms.h
    -rw-r--r-- 1 suz Administ 1133 Jun 4 12:12 obj_dir/Vrtavr_50a_classes.mk

    で make してみる。

    cd obj_dir
    make -f Vrtavr_50a.mk

    そうしたら、Vrtavr_50a__ALL.a が生成された。... なんかいけそうな感触。

    エミュレータじゃなくて これをツールに統合すれば、プログラムや I/O 周り (SPI_SLAVE) のデバッグができそう。SMP もいけるだろう。ちょっと面白くなってきた。

    ただ、こっちは、JTAG 関係は必要ない。こっちに走ると JTAG ツールが後回しになってしまう。しばらくいじるのを我慢しよう。

LCMXO2280C-B-EVN (MachXO 2280 Breakout Board Evaluation Kit)





    LCMXO2280C-B-EVN というのが、Digikey で 2700円で売られているのを知った。

    デバイスは、MachXO-2280 でひとつ前の世代だが、一応 2280 LUT で MachXO2 Pico Dev kit より多い。
    そんなことより、Digikey ですぐ買えて、FT2232 が載っているのが気に入った。

    実をいうと FT2232D は持っていない。ツールでは、FT232R と同じ コード(BitBang) で 対応しようと思っているのだが、MachXO2 Pico Dev kit は、すぐには入手できそうにないし困っていた。

    ツールを作るには、(ツールのテストのために)確実に動くものが欲しいし、安価だし、願ったりかなったりなので、購入することにした。

      ちなみに、秋月の FT2232Dボード 改めて見ると 1450円となんか安くなっている。ただ汎用 JTAG CABLE として使うには、AT93C56 の入手がネック。

    ... というか、これで rtavr のデバッグまでいける。そうなると artemis ボードを作らなくとも済むようになってしまう。artemis ボードを組むのがますます後回しになるが、まぁ経験を積んだ後でも良いかも知れない。いまさら急いでもという気持ちになっている。

      ちなみに、Lattice 純正なのだから書き込みツールは不要。だが、JTAG と内部でつなげて ISP したり、SPI 通信したりするのにツールを使いたい。書き込み機能は不要でもツールの設計の確認のために、おまけで作っておくつもり。

    Lattice の合成ツールを入れるためには、空き容量をなんとかしないといけないのだが、実は SSD も新調した。
    現在の SSD の erase count は 3000 ぐらいで、まだ 1年〜2年ぐらいは持つのだが、使えなくなったときに入手できないと嫌なので、64GB を買うことにしたのだ。

    ところで、『FPGAボードを使う計画』-- ステップ(8) I/O ボードを Spartan-6 で作る。というのがあるのだが、TQG144 では、ピンが足りないことが予想された。かといって BGA など電子工作レベルでは無理。だが、LCMXO2280C-B-EVN は、やたら入出力が多い。

      ピンヘッダで 320pin 分あるが、デバイスは、LCMXO2280C-3FTN256C だそうだ。
    • 製品ページ (英語)

      ユーザーズガイドを見ると LED が 8個載っている。(下の写真の 右:D1〜D8) 。オシレータを内蔵しているし、とりあえずは、これで十分。なにも接続せずにデバッグできそう。

      サイズはよくわからないが、だいたい 7.5cm 四方。(穴の数を数えたら 縦横共 30個だった。-- 7.62 cm 四方)

      ユーザーズガイドを見ると FT2232HL って書いてある。D じゃなく USB Hi-Speed 対応の高速版!これはお得かも。(ちなみに MachXO2 Pico Dev kit は FT2232D も "H" -- ユーザーズガイドに書いてあった。)

      FT2232HL との接続は JTAG の 4 つの信号のみ(JTAG 用ピンヘッダとパラレルに接続)。他は NC でコネクタすらない。JTAGは、シリアルとの互換性をまったく考慮していないが、保護用抵抗が入っている。

      machxo_bo.tck = 0 # ADBUS0/TXD
      machxo_bo.tdi = 1 # ADBUS1/RXD
      machxo_bo.tdo = 2 # ADBUS2/~RTS
      machxo_bo.tms = 3 # ADBUS3/~CTS

      こんな接続。

    I/O ボードは、これで良いのではないかという気がしてきた。FusionPCB の 10cm x 10cm も安くなったし、これをマウントするマザーボードを作っても良いかもしれない。先の話だが覚えておこう。

    ... と思ったのだが、320穴もの ピンを ピンヘッダ-ピンソケットで 接続すると 二度と外せなさそう。だいたい 2x40 を 両側に 1つづつ付けるぐらいが精一杯 のような ...

    そういうことだとすると、いったいどうやって使うのが良いのだろう?

    まずは、コネクタの割り当てを見てみる。

  • J5-J6...J10-J9

      USB コネクタを下にすると、上下サイドに付くコネクタは、上から J5-J6...J10-J9 になる。

      J5 と J10 は信号線がみっちり詰まっていて、GND すらない。一方 J6/J9 は 電源系が多く 信号線はすくない。特に J9は、LED を除くと 信号線は 5 本しかない。(J6 は 12本)

      ただその 5本は重要そうな感じで CLK0-3 と SLEEPN 。

  • J3-J4..J8-J7

      J3,J8 は、作動ペア 2 本づつが GND とともに配置されている。(14ペア)。
      J4,J7 は、2,4..22,24 が GND で、25,27 が N.C. 。

      ケーブルで引き出すのに向いているかんじ。

    ... となると、マザーボードに付けるなら 上下サイドにピンソケットを下向きに付けるのが良いのだろうか? J5,J10 をメインにして、J6/J9 は電源供給(他)を目的に 一部だけ使う .. みたいな。

    逆に、小基板を載せる.. なら 5cm 四方ぐらいのサイズで 済むから具合が良さそう。ただし、アクセス性が悪いから 何を載せるかは悩ましい。

      構想どおりなら、SDRAM と MicroSD スロット x N 。と水晶ぐらい?

      ... おもいだした。5cm x 5cm なら 40pin 分は無理。19x19 のサイズ(穴は 18x18)まで。-- 片側の 4 列をつなげると 反対側に届かない。それなら、片側だけ使うものとして設計すれば良いか。

      中央に J10,J9 を使った SDRAM + クロック ボードを置いて、左右に インターフェイス変換基板 (MicroSD x 4 と ARTEMIS 通信用 2x5コネクタ x 4 + USB みたいなかんじ) を考えてみよう。

      ... 今そういうものを作りたいわけではなかった。今は、そういう構想のもとに、ピンヘッダ/ソケットをどう付けるかだけ決める。

      2x40 低メス (40円) を J5,J6 と J10 に 付けることにして、左右はさわらない ことにしよう。

      C 基板を付けるなら、スルーホールにして、中央に縦にマウント。ピンヘッダは、必要な分だけにしておかないと 外すのがやっかいになる。

      で、とりあえずやりたいのは、セラミック発振子 とか 水晶発振子 で発振できるかのテストぐらい。

    (おまけ)邪な考えだとは思うが、J9 の 上の列 (下から 2 番目の スルーホールの列) で切ってしまうとどうなるのだろう? ひょっとして USB Jtag ケーブルとして使えるのだろうか?

      MachXO は、MachXO2 とは違い JTAGENB というピンはなく ユーザI/O として使えないようだ。ユーザ I/O として使えれば、他の I/O ピンに接続するとか ができるのだが...
      あと、Config は JTAG のみのようだから、切り離した FPGA の利用は難しそうだ。

    当面は FPGA も必要なので、そのようなことは実行しないつもりだが、不要になってしまったら、そういう形で再利用できるかも知れない。

ツールの状況とか

    遅々としてなかなか進まないのだが、ft232r 用の コードはコンパイルが通った。あと、てきとうな conf ファイルの読み込み部分はできた。serjtag に移っているが、serjtag デバイス側に問題があったりして、ちょっと困っている。

    さて、Lattice Diamond をちゃんとインストールしてみた。MachXO2 用の Config で rtavr を試してみると ... エラー。ブロック RAM が 9kb x 3 しかないのが原因だった。RAM 1KB , ROM 2KB に変更してみたら OK 。規模は、548/1140 スライスだった。

    JEDEC ファイルというのが、生成され これを tool->> programmer で ispVM に渡して書きこむ手順。ispVM は、ライタソフトで、FT2232 経由で書きこむことができる。

    書きこむだけなら、ここまでの理解でできることはわかった。

    JEDEC ファイルをどうやって読み込んで、どういう JTAG 操作で 書きこむのかまでは、よくわかっていないのが現状。『USB-Blasterもどきの製作』の DDT#1付録LaticceXP2-5E書き込みソフト を見させてもらって理解しようと思う。

    LCMXO2280C-B-EVN (MachXO 2280 Breakout Board Evaluation Kit) は、すみやかに NARITA まで来たのだが、まだ受け取れていない。箱を開けて即書き込みできる状態にはなっているが、どうやってテストするかが、まだまだ。

    まずは、JEDEC ファイル

  • ELM: PLDフューズファイルについて (1997.7)

    が参考になった。実際のファイルを見ると

      ^B
      *
      NOTE xxx が続く


      QF486576 # 486576 bit の情報
      G0*
      F0*
      L000000
      1/0 が続く
      *
      CC8F6*     # データのチェックサム(16進数)
      N User Electronic Signature Data*
      U00000000000000000000000000000000*
      ^C6523     # ^C の後 文字コードのサム(16進数)

    デリミタは、* だが行末にしか来ないようだし、簡易パーザなら簡単に作れそう。

    さて、どうやって Config するものなのか ... XP2Write を眺める。

    int JtagCableOpen(int num=0);
    void JtagQueSIR(PUCHAR tx,unsigned bitadr,unsigned bitlen,int read=0);
    void JtagQueSDR(PUCHAR tx,unsigned bitadr,unsigned bitlen,int read=0);
    void JtagQueIDLE(unsigned clocks);
    int JtagFlushQue(PUCHAR rx=0,unsigned rxbits=0,int check=1);
    void JtagCableClose();

    jtag.h で定義されている Jtag のプリミティブはこう。-- 実は JTAG の操作をよく知らない。SIR/SDR を基本とすれば良いわけか。なるほど。

    で、XP2WriteDlg.cpp にこれを使っているコードがある。コードは長いがなにをやっているかはわかりやすい。

    tx[0]=0x16; //IDCODE
    tx[0]=0x1C; //Preload
    tx[0]=0x15; //Enter programming mode
    tx[0]=0xB2; //Read status
    tx[0]=0x03; //Erace
    tx[0]=0x1E; //Leave programming mode
    tx[0]=0x21; //InitAddress
    tx[0]=0x67; //ProgramIncrRti
    tx[0]=0x52; //Program/Status
    tx[0]=0x1A; //program user code
    tx[0]=0x21; //Reset addr
    tx[0]=0x17; //Read Usercode
    tx[0]=0x45; //program sed crc
    tx[0]=0x44; //read sed crc
    tx[0]=0x2F; //program done bit
    tx[0]=0xFF; //Bypass ...to enter usermode?

    8bit の IR を登場順に拾っていくとこんなかんじ。-- 随分あるものだ。

  • TN1086: MachXO JTAG Programming and Configuration User's Guide (pdf)

    DS1002: MachXO ファミリ データシート (日本語 pdf)』には、これを読めと書いてあるのだが、こんな情報は載っていない。

      分かるのは、JTAG 1532 を通して Flash に書き込む方法と 直接 Config する方法があり、Flash からの Load指令(Refresh) もできるということぐらい。

    ... JTAG 1532 では、BSDL ファイル にコンフィグ方法が定義されている ... らしい。

      ここからダウンロードして眺めてみることにしよう。

      見たのだが... なにかそれらしいことが書いてあることは分かる。IR の定義も分かる。だが、アルゴリズムは直感的にはよくわからない。XP2WriteDlg.cpp と XP2 とを見比べて みるしかないか。それで理解が進んだら、今度は XP2 と MachXO,MachXO2 を見比べる -- って そんな手順以外ないのだろうか?

        よくよく見たが、アルゴリズムなんて載っていない。載っているのは、IR に対応した DR の名前と bit 幅。


        DR IR XP2_5E XO_2280 XO2_1200
        ISC_ADDRESS  ISC_ADDRESS_SHIFT   1938 1116 333
        ISC_DATA   ISC_DATA_SHIFT   638 436 1080
        ISC_PDATA ISC_PROGRAM,ISC_READ 638 1080
        ISC_PDATA VINCR_RTI,ISC_READ 436
        ISC_SECTOR ISC_ERASE 8
        ISC_CONFIG ISC_ENABLE,LSC_ENABLE_X 8
        ISC_CONFIG ISC_SETUP,READ_SETUP 4

        ちょっと比べてみたのだが、定義上は微妙に違う。手順も似ているが微妙に違うのだろうか?

        あと、『Lattice XP2のC-SRAM書き込みモードに対応しました』という記事を発見。ただ、そういうことが可能であるということしか分からない。

        どうも Lattice の場合 config は、Flash に対してやるものであって 直接 config は、optional みたいな感じがする。MachXO2 の場合、SPI や I2C でも config できるが 直接 config は、JTAG だけだし。

        一番の問題は、ドキュメントを見付けられていないこと。

        TN1204 MachXO2 Programming and Configuration Usage Guide の Appendix B. MachXO2 Slave SPI Programming Guide に 例が載っている。

        この例が、XP2Write のコードに似ている。比較していけば、MachXO2 の Flash への config はできるようになるかも知れない。だが、もっと 直接説明した ドキュメントはないのだろうか?

      ちょっと大変そうなかんじだ。もともとは、(後で困らないような) Jtag のメソッドを決めるために 調べてみようと思っただけ。その観点でまとめて次にいこう。

    • Lattice の場合、IR コードに多数のコマンドが定義されている。これはちょっと想定と違った。DR に流し込むデータにコマンドも含まれているのが普通だと思っていたのだ。

      設計にあまり影響はないが、SIR と SDR を頻繁に切り替えて使う場合もあることを想定しておく。

      JTAG の扱い方はよく知らないわけだが、デバイスに対して、IR の設定と DR の読み書きができれば良さそうな印象。

      JTAG chain は、とりあえず考えない。当面使う予定のものは chain がない。デバイスの選択という概念は、とりあえずなしにして、カレントのデバイスのみを操作するような API だけ作っていこう。

    • Lattice のコンフィグは、とりあえず必要ない。とりあえず必要なのは、JTAG 使った ISP と通信。これを先にしよう。

      ... といってもデバイスによって手順が違う。デバイスのドライバは必要だが、部分的にサポートするような構造になる。

    • FPGA を直接 config するのと (SPI_FLASH とか)FLASH を書き込むのは全然別のものと考えていた。

      SPI_FLASH の書き込みは、FPGA 内に作りこんだ回路との通信を想定していた。無駄が多いが、Lattice でも MachXO2 ならそのようなものは作れる。とりあえず、その構想のまま行く。

      作りたいのは、ライタソフトではないのだ。あくまで、JTAG を通して通信するのをサポートするツールで その仕組みの応用として FLASH の書き込みができるなら対応を考える。直接 config するのは、これを作るためにも必要だし、基本機能として考える。... ということにしよう。

      MachXO は JTAG 以外からの FLASH の書き込みは できないような感じだが、Breakout ボードしかつかう気がないし そうであれば なにも考えずに 純正ツールで書き込めるわけだから、気にしないことにする。

    BSDL ファイル のチェック

    そういえば、『LatticeXP2のFPGA回路内部へJTAGで通信する』 の記事には、

      JTAGEモジュールを有効にするには、JTAGプライベート命令のIPA(0x32)とIPB(0x38)を使います。インストラクションレジスタにIPA命令を入れるとJTAGEモジュールの信号系統1が有効になり、IPB命令を入れると信号系統2が有効になります。

    と書いてある。これは BSDL ファイルに記載されているのだろうか?

    " IPB (00111000)," &
    " IPA (00110010)," &

    MachXO の場合はこう書いてある。大丈夫そうだ。

    "PRIVATE (00000010, 00111010, 00110010, 10111010, " &
    "11011101, 11001010, 00111000, 01100000, " &

    だが、MachXO2 の場合、PRIVATE の中で記述してあるだけ。
    JTAGF という機能はあるから出来ないわけではないが、enable にする手順が違うかも知れない。ただ、XP2 の場合も 同様だからたぶん大丈夫だろう。(内容訂正)

    ここでつまずくと全然面白くない。MachXO2 Pico Dev kit が欲しかったが、とりあえずは、MachXO Breakout で良かったのかも知れない。

FPGA との通信の方法(めも)

    一番作りたいものは、これなわけだ。いったいどうするのか整理しておこう。ただし、どれも未確認なので要注意。

    MachXO の場合は、『LatticeXP2のFPGA回路内部へJTAGで通信する』 の記事がとても参考になる。

    Diamond 1.1 で使った限り違うのは、lscc/diamond/1.1/cae_library/synthesis/verilog/machxo*.v に定義があり、インスタンシエートする必要はないということと、MachXO では、JRSTN ではなく JRST になっているということぐらい。

    さて、IPA と IPB を 使って 2 つのチャネルが作れる。 『JCE1は、Capture-DRもしくはShift-DRのときにHになります。』ということだから、JCE1/JCE2 が H のときにそれぞれのチャネルが動作するようにしておけば良いのだろう。

    使い方は、チャネル1(IPA) は、SPI として 通信に使う。チャネル2(IPB) は、rtavr の ISP に使うことにした。SPI_FLASH の書き換えは、rtavr の SPI を通して接続する予定(希望)だが、そんなまどろっこしいことをせずに、SPI_FLASH の線と直結するかも知れない(未定)。いずれにしても チャネル1に接続。

      これらの通信を、JTAG のフルスピードで行うとまずい場合がある。rtavr の ISP は、rtavr の 周波数 (CLK2X / 2) の X 倍を超えてはいけないとか なにか条件がある。チャネル1(IPA) を rtavr の SPI につなぐ場合は、もっと厳しく 1/2.5 以下とか。しかも連続で送れないとか ファームウェアの都合に起因する条件もある。忘れてはいけないのでメモ。


    ___ ___ ___ ___
    JCK _____| |___| |___| |___| ....
    _______________________
    JCE1 & JSHIFT _____| |____

    IN SFT IN SFT IN SFT

    どうもこんなタイミングで動かしてやれば良いらしい。

    注意点は、両方とも 論理が逆なので、SPI と接続するときは反転して入力。MSB first か LSB first かは通信規約によるが、普通の SPI なら MSB first 。

    あと Shift-DR でしか使えない。いったん Shift-DR に入ったら その状態でずっと使うのが基本。bit 同期を取り直すなら、Shift-DR を抜けて再度 Shift-DR に入り直す。

    ISP はいまのところ RESET 状態でしか使えない。( JCE2 & JSHIFT ) を rtavr の RESET に入力することにしよう。

      rtavr で、CPU を一時止める機能は、作れないことはないのだが、そうなると ISP に RESET のための レジスタ定義と レジスタへのアクセスメソッドの追加が必要になる。面倒というより論理が増えるし、メリットも感じないので とりあえずパス。

    MachXO2 では、IPA/IPB がない。どうするのかは、要調査。 でも たぶん同様。

    さて、同じ機能を Spartan-3A で使うには BSCAN_SPARTAN3A を使う。これもチャネルが2つある。チャネルの選択は同様で、IPA/IPB の代わりに USER1(0x02)/USER2(0x03) を使う。

    同様の定義にするなら、JCE1/JCE2 , JSHIFT の代わりに SEL1/SEL2 , SHIFT を使う。TCK も同様だと思うのだが、タイミングが違うかも知れず扱いかたが変わるかも知れない。TCK の代わりに DRCK1/DRCK2 を使ったほうが良いかもしれない。こちらは、Shift-DR と連動するので確実かも。(その場合は、SHIFT との AND は不要 -- というかするとまずいかも)

    Spartan-6 では、また違うのかも。4 つのチャネルが定義できて module の仕様も変わった。要調査。

Xilinxの config の方法(めも)

    FPGA の config をどうしても作らないといけないのは、自作 ARTEMIS ボードの Spartan-3A 。-- CABLE が独自だから代用ができない。

    ただ、基本はすごく簡単なような ...

    JPROGRAM にして CFG_IN で bitstreame の内容を叩き込んで JSTART 。これだけのような ..

    ただ、チェックとかはしないといけない。ステータスを見るには、READ_STATUS のシーケンスを CFG_IN で流して CFG_OUT で読むようだ。

    SYNC_TIMEOUT
    SEU_ERR
    DONE
    INIT
    MODE
    VSEL
    GHIGH_B
    GWE
    GTS_CFG_B
    DCM_LOCK
    ID_ERROR
    CRC_ERROR

    xulaload』のコードを見るとこれだけある。ちゃんと終了したか 。エラーなら理由は何かぐらい見ないと。

      INIT_B を接続したが、不要なのか。ちなみに M1/M2/PROG_B は、SPI_FLASH からのロードを強制的に行ったり、スレーブシリアルモードにしたりする場合に使い、普通は不要。

      ついでに書いておくと 相手が入力専用の TXD 以外 は抵抗を入れるべきだった。(スペース的に入れられたかどうか分からないが)。

    同じようにしていろんな情報が取れるようだが、そこまでしなくて良いだろう。

    Lattice のデバイスも このレベルなら簡単なのだろうが ... 今はよくわからない。まぁぼちぼちやろう。

通信機能のプロトコル

    SPI をシリアルのように使いたい。どのような通信ルールにするか。

    JTAG を使うのだから HOST 側はポーリングしないといけない。これはやむを得ないとして...どういうやり方が良いのだろう?

      (案1)ステータスを読む/送信する/受信する/ といったコマンドを作る。

      (案2)0xff は、データがない という意味にして、送信データがある場合は、データを送り ポーリングする場合は、0xff を送る。受信も同様で、データがなければ 0xff が読める。

    (案1)は、ありがちで悪くなさそうなのだが、コマンドを決めないといけないし、変更すると混乱するから決めたものをずっと使うことになる。コマンドを決めるのに悩みそうだし、拡張が可能だから安易に拡張したくなるという罠もある。

    (案2)は、シリアルの代替にしか使えなさそうだが、その分明快だ。こっちにしようかと思う。

    ツールでは、terminal-mode というモードにして、このモードに入るとキー入力を送り 、受信データを そのまま表示する。MSYS の rxvt の上で動かすと 端末ソフトで通信しているのとあまり変わらない感じになるはず。モードから抜けるのは、~. とか。

SVF ファイルと ispVM

    SVF ファイルとは、どういうものか知らなかったので ググってみたら TEXTファイルだと書いてあった。
    MachXO2280 への Implement はできていたので SVF に変換して読んでみたところ ..

    なんだか可読性が良いではないか。これなら、なにをやっているか(かなり)理解できる。随分参考になりそうだ。この情報と XP2Write を合わせて見れば、ライタも作れそうだ。

    で、MachXO2 のほうも同じようにしようとしたら .. Export Files に JEDEC file の項目が出ていない。
    理由がわからないので、新しい ispVM だけ インストールしてみることにした。

    で、インストールされるものを眺めていたら なにかソースコードもある。
    CPUEmbedded/PCM, CPUEmbedded/SCM, ispSlimVMEmbedded, ispVMEmbedded, SSPIEmbedded ... なんだろう?

    JEDEC file の項目が出ない件についてはわからない。Diamond 1.2 の日本語ドキュメントが出ていたから 早々と 1.2 にするのが良いのかも知れない。

      update チェックをしたら B1.1.01.50.42.10_xo2_1200JEDEC というそのままズバリな名前のパッチがでていた。 10MB ほどなので、Diamond 1.2(既に出ていた)にせずに パッチで済ませることにした。

      XO2 も いずれ 2000/4000/7000 が出てくる。バージョンアップは、そのときでいいや。

      (追記) 確かに JEDEC は作れた。しかし ... SVF への変換でエラーになった。Diamond 1.1 付属の ispVM は、17.9 。単独で インストールする ispVM は、18.0 なので試してみたが、これもダメ。待つしかないようだ。

    あと ググっていたら、『XAPP058 には、エンべデッド SVF ファイル プレーヤのソース コードが掲載されています。』という情報も見付けた。ちょっと見てみようかと思う。

    たぶん JTAG レイヤーの プリミティブは、こういうのと同じレベルにするのが良いのだろう。参考にしたい。

      ちょっと 『XAPP058 (日本語 pdf)』 を読んでみた。XSVF というバイナリに変換したものを入力して JTAG を操作するエンジンがあるらしい。

      で、フロチャートを見ると XSIR, XSDR に加えて XRUNTEST の 3 つの処理しかない。XRUNTEST は、delay の役目がある。sleep とは違い クロックを出している。MMC/SD カードで クロックを出していることが重要な場合があったが、JTAG はどうなんだろうか? -- 少なくとも ユーザ回路での SPI 通信で クロックだけが欲しいような設計はあり得る。

      そういうプリミティブも必要そうだ。あと API を決める上では、SPI通信が悩ましい。rtavr の場合、バイトデータを連続して送ると ファームウェアの処理が間に合わないのが明白。クロックを 100kHz ぐらいまで落とせば良いわけではあるが... せめて SPI をダブルバッファ化すべきかも知れない。あるいは... FIFO の CPI を使うことにして、SPI ブリッジを入れる... とか。

      少なくとも クロックだけを動的に変更する API は必要そうだ。

    SSPIEmbedded をちょっと見たのだが、『Slave SPI (SSPI) Embedded』が名称。 algorithm file and data file. を入力して SPI 経由の コンフィグをするものらしい。algorithm file は、コンフィグの手順を抽象的に定義したものというより 単なるステートマシンのパラメータみたいな気がする。

    API を決める上での 調査は、これぐらいで良いだろう。

JTAG レイヤの API

    void jtag_go(CABLE cbl,int state);

    void jtag_init(CABLE cbl);
    void jtag_IDLE(CABLE cbl, int ms, int count);
    void jtag_SIR(CABLE cbl, unsigned char *buf, int bit_len, int flags, unsigned char *rcv_buf);
    void jtag_SDR(CABLE cbl, unsigned char *buf, int bit_len, int flags, unsigned char *rcv_buf);

    void jtag_SIR32(CABLE cbl, unsigned int code, int bit_len, int flags, unsigned int *rcv_data);
    void jtag_SDR32(CABLE cbl, unsigned int code, int bit_len, int flags, unsigned int *rcv_data);

    こんな風に決めた。

    jtag_init は、RunTestIdle 状態まで持っていく。
    jtag_IDLE は、RunTestIdle 状態 にして、count 分 (tms,tdi) = (0,0) を送出。count が 0 なら ms (ミリ秒) を元に count を計算。

    jtag_SIR/SDR は、ShiftIR/DR 状態にして、buf を送出。flags が 1 なら rcv_buf に TDO を採る。
    状態は ShiftIR/DR のまま。

    jtag_SIR32/SDR32 は、32bit までのデータを扱う場合にコードを簡潔に書くための API 。

    jtag_go は内部関数。RunTestIdle, ShiftIR, ShiftDR にしか行けない。

    XP2Write なんかは、FLush という概念がある。キューに溜め込んでおいて、複数の 処理をまとめてやることでUSBの遅延の影響を少なくするわけだ。

    決めた API では、受信データを要求された時に、自動で SYNC するという構想。serjtag のプロトコルでは、送出のみとか all 0 の送出では、送出データを送らないとか、TDO の値は、要求されたときだけ採取して返すようになっているので 送受信データ量も減らせる。ft245r (BitBang) では、データ量は減らないが、自動で SYNCというのは有効。

    関数は 全部 void 。どうせ受信データをチェックするから、いちいちチェックしなくて良いだろうという考え。

TARGET レイヤの API

    typedef struct target *TARGET;

    struct target {
    int (* sel_chan)(TARGET tgt, CABLE cbl, int chan);
    int (* program)(TARGET tgt, CABLE cbl, unsigned char *buf, int len);
    int (* verify)(TARGET tgt, CABLE cbl, unsigned char *buf, int len);
    };

    int tgtxil_init (TARGET tgt, CABLE cbl, unsigned int device_id);

    とりあえず、こんな風にした。SPI_FLASH の program は、もっと上位のレイヤ。
    program/verify は、FPGA の直接 config で、RAM だけの 書き込みを想定。program/verify は作れなかったら常に ERROR するようにする。

    sel_chan は、簡単だが最も重要。これでお膳立てをして、あとは、jtag_SDR/jtag_SDR32 で通信する。
    ちなみに bitclock を変えるのは、CABLE の API 。

    こんなわけで、ようやくツールづくりが回り始めた。ちょっとがんばってみよう。

いろいろ問題が出た。

    まず、jtag 。

    ShiftIR/DR 状態のまま終わるのは、無理。最後の bit は、TMS=1 で送出しないといけない。

    これで最後という場合は、flags に 0x2 を付けることにした。... で、ターゲットの コンフィグのコードを書いて見たら、全部 0x2 が付くことになった。むしろ続く場合に 0x2 をつけた方がよさそうだ。

    あと、状態が増えた。ちなみに、通信する場合も 1 つのブロックの処理をしたら いったん終わらせた方が良いかもしれない。CS の操作と同じなので bit 同期がとれる。

    次にターゲットの API 。verify できるものなのかどうか良くわからない。xilinx の場合すごく大変そうだし、lattice の場合でも いったんプログラムモードから抜けたら読めるものなのかどうか?

    program のときに verify なり CRC チェックなりをすることにして、verify プリミティブは削除しても良いかもしれない。lattice で verify だけ出来るのなら削除しないが、無理だったら削除することにしよう。

    あと lattice では特にいくつかのパラメータが必要。最初に PRELOAD する bit 幅がまず必要。次に アドレスサイズとデータ幅。

    XP2 と MachXO は、手順がかなり似ているが、違う部分もある。MachXO2 も 多少違うはず。
    これらの違いへの対応は、IDCODE で判断するつもり。

    ... だいぶ具体的なことが書けるようになってきた。もうすぐベースは出来るだろう。

まだまだ

    なんと、Lattice の IDCODE は、ファミリで 1種類だった。... ということは IDCODE をパラメータとして渡しても コンフィグ できない。で、xx_init のパラメータは、LCMXO2280 とか名前で渡すことにした。

    あと、Lattice XP2 と MachXO では、似ているものの やはり違いは大きい。SVF ファイルを見ると違いが良く分かる。

    /* XP2 only */
    #define ISC_PROGRAM_STATUS 0x52
    #define ISC_ERASE_DONE 0x24
    #define PROGRAM_SED_CRC 0x45
    #define READ_SED_CRC 0x44

    /* XO only */
    #define ISC_SRAM_ENABLE 0x55
    #define DATA_SHIFT 0x02

    SIR で これだけ違う 命令を使う。ステータスの読み方なんかも違う。program() 自体別立てにした方がすっきりしそうだ。

    一方 Xilinx の方は、IDCODE でデバイスまで分かる。だが、デバイスが違っても コンフィグするコードは FPGA なら 同じ。

    さて、jed ファイルの読み込みも いんちきパーザを作ったので読み込めるようになった。デバイス固有のパラメータは、プログラムの中にテーブルを作って対応することにした。MachXO に関する 下位レイヤは揃ったことになる。後は上位レイヤだが、なかなか悩ましい。

MachXO2 の SVF が作成できた。

    ispVM には、SVF の作成方法が 2 つある。試してだめだったのは、UFW での 作成で、組み込みの SVF 作成機能は OK だった。それだけでなく、Verify だけする設定とか、SRAM だけ書き換える設定があった。-- ispVM を起動しただけでは UFW しか動かせないので 実際にデバイスが接続されていないとダメなのかと早とちりしてたのだ。

    SRAM だけ書き換える設定は、MachXO や XP2 にもあるから SVF を作れば、想定どおりのライタが作れる。
    問題は、組み合わせが沢山あるから、どういう API にして 関数をどう作るか。

    一応、SRAM への書き込みを default にして、Flash の書き込みは option にしようかと思う。verify も同様。あと ERASE のみというのも、必要なのかも知れない。これは FLASH のみ。

    で、MachXO (LCMXO2280) と MachXO2 と XP2 (LFXP2_5E) に対応するつもり。今 LCMXO2280 は持っているからテストできる。MachXO2 は、1200 以上をこれから使っていこうと思っている。LFXP2_5E は、雑誌付録でまだ入手可能。それ以外は対応するつもりはない。

    ちなみに、Xilinx は、XC3S50A/XC3S200A と XC6SLX9 のみを予定。-- 要するに自分が使う予定があるもののみ。

Lattice の SVF を整理。

    Flash の Erase , Program, Read と SRAM の Program , Read を XP2/XO/XO2 について出力して比べて見た。

    見ているとどうもいくつかのプリミティブに分けられそう。

      その前に、読み書きする対象について。

      XO は最も基本的で コンフィグデータ と USERCODE の 2 つ。XP2 はそれに SED_CRC が付く。で、コンフィグデータの書きかたは、SRAM と FLASH であまり違いはない。-- SRAM に書いて WRITE-BACK しているような印象。

      XO2 は、SED_CRC はないが、FEATURE というのがあるようだ。それに加えて、FLASH での WRITE では、ADDRESS を WRITE している。どういう概念なのか良くわかっていない。また XO2 は、SIR の命令も随分違う。XP2/XO とは、大分違う印象だ。

    まず、Enter_Programming_Mode と Exit_Programming_Mode , この手続きは デバイスが同じなら同じ。

    あと、Program_Done 。更新系では、Exit_Programming_Mode の前に行う。エラーが起きた場合、Program_Done してはいけない(たぶん)。

    この間で、読み書きする。たぶん Erase → Program → Verify(Read) に分けることができて 独立したプリミティブに出来そう。 あと、SRAM と FLASH は、それぞれのプリミティブのパラメータに出来そう。( Program_Done も SRAM と FLASH の区別がいるかも )

    読み書きする対象はいくつかあるのだが、単一のメモリブロックということにしている。サイズは、決まっているので、コンフィグデータ , (SED_CRC/FEATURE) , USERCODE の順に配置するつもり。

    ただ、XO2 がどうなっているか、ちゃんと調べた後でないと確定できない。


    LCMXO2_1200 (SRAM):
    0 - 359639 (333 * 1080) Config data
    359640 - 359671 (32) USERCODE
    LCMXO2_1200 (FLASH):
    0 - 278399 (128 * 2175) Config data
    278400 - 343935 (128 * 512) UFM
    343936 - 344015 (80) FEATURE
    344016 - 344047 (32) USERCODE

    XP2/XO は、SRAM と FLASH に書くデータのサイズが同じで address_size x data_width で計算できた。(データの内容も同じ: 確認済)
    XO2 も SRAM に書くデータのサイズは、address_size x data_width で同じ。

    だが FLASH に書くデータは別のものであるらしい。そして、jed ファイルに入っているのは、FLASH に書くデータ。-- これは困った。jed ファイル は容易に作れるが SRAM に直接書けるものではない。

    SRAM に書くデータ は、ispVM を 起動すれば SVF で 作れるが手順が面倒。

  • TN1204: MachXO2 コンフィグレーションガイド (日本語 pdf)

    に書いてあることが少し理解できるようになった。

    • 設定は、「SpreadSheet View」の「Global Preferences」で行うが、まず GENERATE_BITSTREAM を ON にして .bit ファイルを生成しないと SRAM 用 SVF は作れない。COMPRESS_CONFIG は、.bit ファイルにだけ影響すると書いてあるが、ON にしないと .jed ファイルが生成されない。

    • FLASH のエリアは、CFM と UFM そして、Feature Row と USERCODE 。CFM は、"Configuration Flash" という記述で書かれる場合もある。Flash は、桁 x 行(Row) でアドレスされていて、Feature Row は ひとつの 行(Row) を USERCODE と共に使用する。

      CONFIGURATION のデフォルトは、CFG_EBRUFM となっているが、EBR(ブロックRAM) の初期値を UFM に置くとう意味で、ユーザロジックで書き換えが可能になっている。

    どうも MachXO2 では、SRAM 用のデータを作るのが面倒なようだ。だが、SRAM 用の SVF ファイルから取り出せば 作れないことはない。

    作ってどうするのか?

      Flash を読み書きする ロジックを SRAM だけで動かすように作るつもりだったのだが ..

      まぁ、すくなくとも、こういう特殊なものは、ツールで使うとか用途も特殊。そうであれば、一回作ったものを使い回すはずで、作成の手間は多少あってもかまわないのかも知れない。

      ちなみに 無圧縮 bit ファイルのサイズは、45376 バイトだった。情報量は、359640/8 = 44955 バイトで 差分は、421 バイト。

        Lattice Semiconductor Corporation Bitstream
        Version: Diamond_1.1_Pro duction (517)
        Bitstream Status: Advanced Version 1.62
        Design name: rtavr_test_rtavr_test.ncd
        Architecture: xo2c00
        Part: LCMXO2-1200HC-4TQFP100ES
        Date: Wed Jun 15 05:50:25 2011
        Rows: 333
        Cols: 1080
        Bits: 359640
        Readback: Off
        Security: Off
        Bitstream CRC: 0xF760

      421 バイトのなかには、こういう情報もヘッダとして入っているし、FEATURE ROW , USERCODE が別にあるはず。必要な情報を取り出すこと自体は容易そうだが、無圧縮の bit ファイルを作るということは、設定を変更して Implement しなおすということで、ispVM を起動して設定するより時間がかかる。

    Digilent JTAG SMT1



    あ、Digilent が、FTDI 採用している! ... と思ったら iMPACT から直接使えるのか。

    そうか。JTAG 界 は FTDI があれば、良いわけか。... そうなると 作っているツールは、LCMXO2280C-B-EVN (MachXO 2280 Breakout Board Evaluation Kit) に対応しておけば、万全といえる。

    ただ、EEPROM 設定済みの FT2232 は、Synchronous BitBang Mode が使えないかも。
    -- と思ったが ドキュメントを見る限り、大丈夫なようだ。

      ちなみに、MPSSE の使い方。ちゃんと対応すれば、30MHz もの bitclock で動作できる。

    • AN_135_MPSSE_Basics

      これ読むと MPSSE を使う場合でも Open , Close は同じで良いらしい。FT_SetBitMode からが違う。データの詰め方が違うところは、影響が大きいが、1つのソースで対応できるはず。

    • AN_108 -- これに MPSSE の詳細が書いてあるらしい。

      あと、実効性能は、MPSSE の場合、片道 20〜24Mbps 程度だそうだ。さて、Synchronous BitBang Mode はどれぐらいになるのだろう?

      FT232R と同様に設定可能な bitclock より 実効性能がボトルネックになるはず。FT2232HL のデータシートだと Synchronous FIFO Mode は 25MB/sec 以上と書いてある。Synchronous BitBang Mode は、送信データ量と受信データ量が同じだから 片道 12MB/sec ぐらい? 
      ... CLK の ON/OFF に 2 バイト送信するので、そこまで出るなら 6Mbps ぐらいということになる。

      MPSSE の 1/4 程度なわけだが、Config する程度ならデータ量は、50A , MachXO 2280 , MachXO2 1200 クラスだと 多くて 0.5 Mbit ぐらい。 バウンダリスキャンをして パラレルの Flash に書きこむような使い方だと いくらでも性能は欲しいが、Config する程度ならば十分すぎるぐらい。FT232R 使っても あまりストレスはないだろうと思える。

    ついでにいろいろ見ていたら、Hi-Speed シングルチャネルの FT232H なんてものがある。



    FTDI 純正の モジュール UM232H (1801円) なんてのも出ている。(データシート)

    MPSSE も使えるし、JTAG 用に便利かも。... あとよく見たら CLK 付きの Fast Serial がある。... これは PDI に使えるかも。

ツールの進捗状況。



      jtag_IDLE 20ms = 6.064 ms
      jtag_IDLE 20ms = 19.870 ms
      jtag_IDLE 200ms = 202.916 ms
      ft245r: bitclk 460800 -> ft baud 230400
      jtag_go JTAG_STATE_IDLE - JTAG_STATE_SIR : 4 00000a
      put_tdi_tms_bits 4:0 1100
      rcv_data 0 :
      put_tdi_bits 8:0 01101000
      rcv_data 8 :11011100
      jtag idcode I = 0000003b
      jtag_go JTAG_STATE_EXIT1_IR - JTAG_STATE_SDR : 7 000228
      put_tdi_tms_bits 7:0 01101000
      rcv_data 0 :
      put_tdi_bits 32:0 11111111111111111111111111111111
      rcv_data 32 :11000010000010110001010010000000
      jtag_go JTAG_STATE_EXIT1_DR - JTAG_STATE_IDLE : 4 000028
      put_tdi_tms_bits 4:0 0110
      rcv_data 0 :
      jtag_go JTAG_STATE_IDLE - JTAG_STATE_SIR : 4 00000a
      put_tdi_tms_bits 4:0 1100
      rcv_data 0 :
      put_tdi_bits 8:0 01101000
      rcv_data 8 :11011100
      jtag idcode D = 0128d043
      jtag idcode I = 0000003b
      jtag_go JTAG_STATE_EXIT1_IR - JTAG_STATE_SDR : 7 000228
      put_tdi_tms_bits 7:0 01101000
      rcv_data 0 :
      put_tdi_bits 32:0 11111111111111111111111111111111
      rcv_data 32 :11000010000010110001010010000000
      jtag idcode D = 0128d043
      jtag usercode I = 0000003b
      jtag usercode D = 00000000

    基本的なものが動くようになった。ターゲットは、Lattice LCMXO2280C-B-EVN (MachXO 2280 Breakout Board Evaluation Kit) 。FT2232H + MachXO が載ったボードで、MPSSE ではなく Synchronous BitBangMode を使っている。

    今は、ft245r CABLE ドライバと jtag 操作が一応動いたという段階。LCMXO2280C-B-EVN を使って、config 関係のコードのテストが可能になったし、SPI terminal モードとか ISP でのプログラムのコードを作ってテストもできる。それらが終わったらいよいよ rtavr のテストを開始できる。

    XC3S50A/200A の Artemis ボードの出番がないが、ある程度ツールが動くようになれば、AE-UM232R を使ってテストが出来るようになる。やっぱり最初は、Xilinx の config で、それが出来たら、AE-UM232R 互換ボードで serjtag を使っておなじことができる所まで持っていく。

    まぁこんな手順で進めようかと思っている。

ツールの進捗状況2。

    ツールをテストするため、LCMXO2280C-B-EVN の HDL を作った。

    まずは、内部クロックの確認と LED の ピン割り当てが正しいかのテスト。-- OK。

    次に、JTAG の先に、単にエコーバックする spi_echo と メモリを内部に持った ISP をつけた。

    IPA/IPB が選択されたら それぞれ LED を点灯させる。-- OK。

    エコーバックのテスト :

      spi_test
      30 fe
      31 0c
      32 0c
      33 cc
      34 0c
      35 cd
      36 0d
      37 0f
      38 c7
      39 ce
      ff 0e
      ff ff
      spi_test done

    値は変だが、なにか返って来た。

(続く)
posted by すz at 00:24| Comment(0) | TrackBack(0) | artemis

2011年05月21日

AVR互換コア(SMP化)

AVR互換コア rtavr は、いろんなパーツを外したり付けたりすることができるようになっている。その中には、スタックポインタ(SP)/フラグ(SREG) や ROM/RAM まで含まれる。

で、思いついてしまったのだが、ROM/RAM を共有する DUAL_CORE が簡単にできる。- ROM/RAM を取り外して、外部で 構成するだけだ。単なる DUAL_CORE ではなく、SMP (Symmetric Multiple Processor) だ 。

    これは、是非ともトライしたい。SMP を自分でデザインすることになるとは、予想もしなかった要素だ。ますます、面白くなってきてしまった。ちょっと検討してみよう。

    ( 『bitstreamベースのAVRコア(案)』なんて記事を書いたがどうでも良くなった。準備だけは出来たから、いずれやることにして、凍結しよう。)

SMP でも いわゆる Processor 固有領域というものが必要だ。スタックがあるから 下位 256B は違う領域を指さないと困る。
そうなると下位 128B までにある グローバル変数も プロセッサが違うと 違うデータになる。

共有するのは上位アドレスの領域。

SRAM は 2KB もあるから、両者でマッピングを変える。

    マッピングについては、後で詳細を詰めるとして ... RAM をもっと付けたくなるかも知れない。

    いままで、RAM には、2KB の空間しか渡していなかったが、8KB の空間を渡すように変更しよう。(ただし、8KB のとき 使えるのは、8KB - 64 バイト)。

    サイズの設定は、ROM と同じように RAM_SIZE=2048 といったパラメータにする。

ROM には、プログラムから読み込む機能があるが、2つのポートを それぞれの AVR に割り振ると それができなくなる。プログラムメモリを節約できるかわりに、初期値付きデータが利用できなくなったりして 使い勝手が低下する。それに ISP でも 2 つ目のポートを使っている。

    やはり、gcc の普通のプログラムが動かないのは論外だし、ISP も使いたい。

    プログラム と データを同時にアクセスしないよう AVR のパイプライン制御に手を加えると、CPU あたり 1 port で済ませることが可能になる。(従来のAVR は LPM命令でそうしていた)

    ... このコードを実装してみた。変更する所を最小にするために、見かけは Dual Port だが、競合しないことが保証されているので、1 port しか使わないようにしたわけだ。

    define は、ROM_PSEUDO_DP 。

    これをベースに、擬似 4 port の ROM module を作ってやれば良い。 ISP から見るとインターフェイスが 2 つになる。が、実体は 1 つなので、どちらを使っても良い。

あと、プロセッサ間の通信。メモリを共有しているから、基本的にデータの転送は不要だ。ロックの命令は作るつもりはない。同期制御には、イベントの通知だけを使う。-- これは USART を相互に接続することで、対応しておこう。(... 最初の考え)

    一旦シリアルにして、またパラレルに戻すのは無駄が多い。インターフェイスは、USART だが実際はパラレル ... FT232R と FT245R の関係 のようなモジュールを作っておきたい。

    それに、FIFO 化もしたい。USART は 既に 1 つの FIFO に対応しているから、少し仕様を追加するだけで、使い勝手良く実装できそうだ。

    ... これについては、『AVR互換コア(FIFOモジュール)』の記事参照。

IOR は独立に持つ。SP/SREG が含まれているし、通信するにもデバイスを独立に制御できなくてはならない。

  • プログラム空間が 1 つであれば、プロセッサ ID が必要だ。attiny40 ならば、そういうデータを置く領域が 64bit の空間にある。-- rtavr はどうしよう。

    現状 NVMCSR を使って ROM のプロテクトをいれている。DUAL CORE なら 相手の RAM のプロテクトを入れたい。どうせ仕様変更が必要なら、そこに プロセッサ ID を割りこませよう。

  • IOR のデバイスの構成は、ifdef になっている。現状だと CPU0 にだけ 特定のデバイスを付ける... といったことができない。同じデバイスを両方とも持ち、空間や割り込み番号、ポートへのマッピングは同一になってしまう。

    これは... 一体どうしたら良いのだろう?

    rtavr は、IOR を外すことさえできる。SMP 専用の IOR を作り、外部で接続することは可能だ。だが、デバイスの実体が 1 つだとすれば、調停機構が必要になる。IOR 側だけでなく、コア側にも リクエストと ACK/NAK の概念を入れないといけない。あと、割り込みもどういう風に制御するのか設計が必要。

      ROM の調停機構が入ったから、これをヒントに軽く検討してみよう。

      まず、IOR へのアクセスには、IN/OUT CBI/SBI と 条件スキップの SBIC/SBIS 命令、さらに X/Y/Z レジスタ間接の LD/ST (+LDD/STD) 命令がある。

      レジスタ間接は、アドレスが確定するのが遅いから、調停したくない。-- この条件から IOR のDual Port 化は必要ということになる。ー アクセスはできるが、競合した結果は保証しないという風にまず持っていくわけだ。その後で実際には競合しないように制御を追加すれば良い。

      さて、IN/OUT CBI/SBI と SBIC/SBIS は、アドレスが 6bit しかなく、INST にアドレスが入っているから、S1 で速やかに判断できる。S2 で 実際に使う 1 クロック前に 判断できるので、競合したときは、パイプラインストールさせれば良い。

      ここでひねりを入れる。SBIC/SBIS の後続命令が CBI/SBI , IN/OUT なら 続いて IOR を専有させる.. と見事にロックができる。( ただし、2 つの命令の間で割り込みが起きないようにしておかないといけない。)

      ロックする対象のレジスタは、なんでも良いが ソフトで使える GPIOR (0/1/2) というのも用意する。( 普通の AVR にはあるが、モデルとなった attiny40 にはないので追加する )

      (追記) ロックする対象のレジスタは、0 - 0x1f の範囲。 CBI/SBI と SBIC/SBIS はその範囲しかアクセスできない。
      ... そういえば RAMWIN の RAMDR が 0x1f , RAMAR が 0x20 でなぜ半端なとこに置くのか不思議だったが、こういう理由があったのか。

    ... どうも作ることは、可能そうだ。ならば是非トライしたい。

RAM空間の定義

    まず、いままで RAM をどう使っているか整理しておく。

    RAM物理アドレス 論理空間
    (RAM PHYS) (VIRTUAL ADDR)
    +----------+
    | |
    0x0040-0x0800 | A | 0x0040-0x07ff
    | | (0x0840 - 0x0fff)
    +----------+
    0x0000-0x003f | B | 0x0800-0x083f
    +----------+

    アドレスに IOR 空間の分を加算せず サイクリックに使っている。B の部分は、0x800-0x840 で見えるわけだ。ちなみに、デコードをさぼっているので、0x0840 - 0x0fff も A の部分が アクセスできてしまう。

    考慮すべき要素:

    • LDS/STS 命令は、RAM の下位 128B しかアクセスできない。空間で言うと 0x0040 - 0x00bf 。

    • AVR_Toolchain の設定は、attiny40 と同じにしているので、RAM は 256B しかない扱い。初期化も 256B までしかしないし、スタックポインタも 0x013F に設定される。

    • スタックのアドレスは、再定義することが可能だ。また、malloc のプールの範囲も再定義が可能。

    これを DUAL_CORE 化でどうするか ...

    RAMの下位アドレスは、プロセッサ固有空間にしなくてはならない。malloc のプールなどがあるから、256B と限らず もっと大きくしたい。かといって 共有空間では同じアドレスでアクセスしたい。

      ロックがないから、共有のプール領域の管理が難しい。それぞれのプロセッサが管理する領域を持つとすれば ... 相手が割り付けた領域を 使うことはできるが、相手しか free できない。

      まぁ、AVR で malloc を使ったことすらないのだが... 。

      (追記) ロックは可能になったから、共有のプール領域の管理が普通の SMP マシンのように出来る。プロセッサ固有空間のサイズを RAM 容量に合わせて変更できるようにしてみたが、使わなさそうだ。

      ちなみに、ロックは割り込み処理との排他にも使える atomic 操作。シングルプロセッサでも有効に使える要素がある。

RAM マッピング

     - CPU 1 では、RAM の 下位 1KB に対して アドレス の bit 9 を反転する..というのはどうだろう?

    CPU0 CPU1 WP(self)
    +----------+ +----------+ WP(other)
    0x0800-0x083f | PSB(1) | | PSB(0) | x o
    +----------+ +----------+
    0x0400-0x07ff | COMMON | | COMMON | x x
    +----------+ +----------+
    0x0240-0x03ff | PSA(1) | | PSA(0) | o x
    +----------+ +----------+
    0x0200-0x023f | PSB(0) | | PSB(1) | o x
    +----------+ +----------+
    0x0040-0x0200 | PSA(0) | | PSA(1) | x o
    +----------+ +----------+

    PSA(0) プロセッサ固有A CPU 0
    PSB(0) プロセッサ固有B CPU 0
    PSA(1) プロセッサ固有A CPU 1
    PSB(1) プロセッサ固有B CPU 1


    共有領域は、RAM_SIZE - 1KB 。

    プロセッサ固有A アドレスに + 0x200 すると 相手の データにアクセスできる。だが、プロセッサ固有B は、一種の HIGHMEM でややこしい。

    自分用のメモリだが、RAM のライトプロテクトをかけると、相手ではなく自分が書けなくなる。相手からは自由に書けるのだが、8KB のときだけ相手は見えない。

    この制御は、外部でも出来るが、CPUID を rtavr の中に持たせるので、rtavr の中でも出来る。-- rtavr で制御することにしよう。

    ちなみに CPUID は、rtavr のパラメータにする。

ロックの実装

    まず、-- 条件スキップの SBIC/SBIS 命令に続く IN/OUT , CBI/SBI の間では割り込みを入れないというところ -- こんなので良いのか検討してみよう。


    // 0x81: CPU0, 0x82 : CPU1
    if (bit_is_clear(GPIOR0, 7)) GPIOR0 = 0x81;
    if (bit_is_set(GPIOR0, 0)) { // ロック成功
    :
        GPIOR0 = 0x0; // アンロック
    }

    こういう使い方はできる。だが、ロック変数を最大で 3 つまでしか持てない。

    そうなると、二重ロックを使わざるを得ない。

    #define bit_set(port,bit) { port |= (1<<(bit));}
    #define bit_clear(port,bit) { port &= ~(1<<(bit));}

    if (bit_is_clear(GPIOR1, 0)) {
    // 0x81: CPU0, 0x82 : CPU1
    if (bit_is_clear(GPIOR0, 7)) GPIOR0 = 0x81;
    if (bit_is_set(GPIOR0, 0)) { // LVL1 ロック成功
    if (bit_is_clear(GPIOR1, 0)) { // LVL2 ロック成功
    bit_set(GPIOR1, 0);
        GPIOR0 = 0x0; // アンロック LVL1
    :
    :

    bit_clear(GPIOR1, 0); // アンロック LVL2
    }
    }
    }

    LVL1 ロックは、LVL2 ロック変数を変更する権利だと考えれば、別に GPIOR1 にロック変数を置く必要はないのかも知れない。

    まぁとにかく、複数命令間でアトミックでないと困るのは、 GPIOR0 = 0x81;

    割り込みを入れないとか、2 連続でアクセス権利を獲得できるのは、

      条件スキップの SBIC/SBIS 命令に続く IN/OUT , CBI/SBI で 同じアドレス。

    という条件が良いかも知れない。

    (追記) RAMWIN のことを忘れていた。
    RAMWIN は、IOR 経由で RAM にアクセスできる機能。最初の実装は、RAM の dual port を使っていたので、SMP では使えないものと思い込んでいた。

    だが、これを使えば、RAM の任意のバイトに対し LVL1 ロックが可能ではないか。


    unsigned char *lock;
    unsigned char lock_val = (NVMCSR & 1) ? 0x82 : 0x81;
    // 0x81: CPU0, 0x82 : CPU1
    cli();
    RAMARH = (uint16_t)lock >> 8;
    RAMAR = (uint16_t)lock & 0xff;
    if (bit_is_clear(RAMDR, 7)) RAMDR = lock_val;
    if (bit_is_set(RAMDR, 0)) { // ロック成功
    sei();
    :
    cli();
    RAMARH = (uint16_t)lock >> 8;
    RAMAR = (uint16_t)lock & 0xff;
        RAMDR = 0x0; // アンロック
    sei();
    } else { // ロック失敗
    sei();
    }

    こんな使い方ができる。lock 変数は、共有領域でないといけない。

    こういうことならば、RAMWIN の機能をちゃんと実装しよう。

対応状況

  • ROM_PSEUDO_DP

    これは、ROM 領域を LD/ST(+LDD/STD) でアクセスする場合に、命令の読み込みと競合しないようにする。ROM とのインターフェイスは、相変わらず DUAL PORTのままだが、ROM 内で SINGLE PORT 化可能になった。

  • SUPPORT_LOCKING

    『条件スキップの SBIC/SBIS 命令 の後続命令 が、同じアドレスに対する IN/OUT , CBI/SBI ならば、その間に割り込みを入れない』

    .. いまのところこれだけの機能。これは、比較的簡単に入った。

    だが、妙なことに規模があまり増えない。... 調べてみると SBIC/SBIS 命令の S0 でのプリデコード PD_SBIX が規模を減らす効果があった。さらに調べると、NEXTPC_TUNE でオプション化されていた PD_EXT (命令群のプリデコード)も、同じく規模が減る。この 2 つを 標準に変更。

    さて、今の SUPPORT_LOCKING は、まだまだ布石。IOR の調停機構にお伺いを立てて ACK を受け取らない限り パイプラインをストールさせる機能も入れる。... だが、それをする前に、IOR の Dual Port 化を完了させなければならない。

  • IOR_HAVE_GPIOR

    0 - 0xf の 16 個のアドレス範囲に対して GPIOR をサポート。

    .. FF で作るより、分散メモリで作った方が 規模が減る。なにしろ 1:16 だ。1 つの GPIOR を作るコストで 16 個分用意できる。また、この変更に伴い、CPI0/CPI1 のアドレスを移動。

    実装は、レジスタの下に置くという風にした。読み出しで、同じアドレスに 他のレジスタがなければ GPIOR を読み込む。書き込みの方は、レジスタがあっても書きこんで構わない。

    ただ、デコードに対するオプションが、LARGE_MAPPER , MUX_TRI , MUX_OR , +デフォルト とあって実装の組み合わせが増える。MUX_TRI , MUX_ORは、『レジスタが上にない』という意味の 信号を定義しないといけなくて特に面倒。なので、MUX_TRI , MUX_ORを切り捨ててコード削除。今後 MUX_TRI は使えなくなる。 MUX_ORは、使えるが IOR のサブモジュールに対する指定に限定。

  • IOR_HAVE_RAMWIN, IOR_HAVE_RAMWIN_HA

    これを Single Port でちゃんと実装することにした。 IOR_HAVE_RAMWIN_HA は、RAM の上位アドレス(HA) を指定する機能で、アクセスしやすいように 仕様変更した。

    実装する際にアドレス空間について見直した。もともとは、単に RAM の物理アドレスを差すだけだったのだが、CPU1 からアクセスする場合、アドレス変換が入らないと使いにくい。また、RAM のライトプロテクト機能も効かせたい。

    ... というわけで、アドレス変換は少々面倒なことになった。ちなみに対応コードは rtavr.v 。

    だいぶ進んだが、IOR Dual Port 化への道は遠い。

    メモリなどと違って、リソースの種類が沢山あるから、恐ろしく面倒なのだ。

    まずやらなければならないことは、CPU 固有のリソースと装置全体のリソースに分けること。

  • rtavr_ior_ps.v

    CPU 固有のリソースは、SREG/SP , INT0(+INT1) , NVM , RAMWIN 。それに加えて TMR0 / CPI0 ということにした。CPI0 は、Dual Port 化 IOR 内で クロス接続の予定。

    まずは、rtavr_ior.v を rtavr_ior_ps.v にコピーして、上記のものだけにする作業をした。その際に デコードに対するオプションを、LARGE_MAPPER 相当のみに機能削減。

    あと、INT0(+INT1)の入力信号の定義と、『アドレスに対応するレジスタが存在しない』という意味の 信号を定義。

    この作業は、削除が主なので比較的楽なほう。

  • rtavr_ior_ms.v

    次は、rtavr_ior.v を rtavr_ior_ms.v にコピーして、CPU 固有のリソースを削る。残ったものは、PORTA/B/C , USART, SPI , TWI(未実装), CPI1 。

    CPI1 は、外部との接続用で CPI0 と違う扱い。

    こちらもアドレスデコードは、LARGE_MAPPER 相当のみに機能削減。... これは、やりすぎかも。デフォルトだったデコード方式は、サブモジュールで 1 つに一旦まとめるというもの。Dual Port 化したとき 2つのデコード方式で意味が変わる。

      LARGE_MAPPER 方式は、READ に対しては、レジスタ1つ1つを独立にアクセスできる。コードの修正も楽な方。そのかわり、実際の配線量が多い。

      WRITE に関しても似た様なもの.. のはず。ただ、すべての レジスタに対して 入力データのセレクタが付くことになる。

      この配線量が非常に多そうな気がする。SUPPORT_LOCKING では、アクセスしようとするアドレスも仕様にいれているので、IOR 調停で プロセッサ固有のレジスタ以外は、同時には 更新できないという風にすると セレクタを 1 つにできて 配線量を減らせるはず。

        これは間違いだった。LARGE_MAPPER であっても、WRITE の場合はサブモジュール単位で 1 データ。レジスタ単位で WRITE データを別にはできない。1 サブモジュールに対して同時に WRITE すると、2 つのレジスタに同じデータ(CPU0側)が書きこまれる。... どうも凝ったことしないでも良さそうだ。

        GPIOR も事情は同じ。WRITE の場合 1 つのデータしか書けない。で、アドレスデコードを適当にすると、ひどいことになる。

      サブモジュール方式だと、同一モジュールに対して 同時にはアクセスできない。アドレスが 1 つしかないから、どちらかのアクセスを選ばないといけない。同時にアクセスされた場合の動作は未定義。-- 実装上は CPU0 優先にする。

      ... こんな風になる。サブモジュール方式の方が良さそうなのだが、どうせだいぶ作り直さないといけないので、一旦削除で良いだろう。


  • 割り込みのルーティング(ToDo)

    装置で共有するデバイスの割り込みを どちらの CPU に回すかの 機構がいる。

      両方ともに同じ信号を送り、ACK を 単に OR することで、どちらかが ACK を返せば割り込みがクリアされるようにした。基本どちらかだけが、割り込みを処理するようにしないといけない。両方のCPU で割り込みを許可すると、同時に両方で割り込みが入ったり、片側だけに割り込みが入ったりする。好ましくない挙動だが、とりあえずはこれでも良いだろう。

      本来なら、割り込みを許可している CPU を 1 つ選ぶ 。両方許可していたら SLEEP している方を優先。
      .. といった制御が良さそうだ。-- これはいずれ。

  • IOR アクセス調停機構(Todo)

    Dual Port 化の実装方法の違いで、調停のしかたも随分違うようだ。

  • まとめ

    こんな風に IOR Dual Port 化では、コードが大きく変わる。一旦 IOR の ソースを分岐させるが、最終的には、Dual Port 化 IOR を Single Port でも使うようにするつもり。

    Version 0.9 として リリースする予定だったが、大更新中なので、なかなか難しい。コードが落ち着かないので スナップショットも作る気になれない。ソースコードの提示は形が定まった後にする。

SMP化の効果

    正直なところ、SMP化してどれだけの効果があるものなのかよく分からない。

    AVR互換コア(FIFOモジュール)』の記事で書いた CPI を使って rtavr 同士をつなげば十分のような気がする。

      一方SMP化自体には意味がある。第一に rtavr を特徴づけることができる。SMP の 8bit 組み込み向け CPU なぞ世の中にほとんどないはずだ。作る立場として、意義を見いだせることは重要なのだ。

      SMP としての特徴は盛り込むつもりだから、教育用としても意味があるはずだ、SMP 制御の基礎を簡単なコードで動かしてみることができる。

    CPI だけを使った場合と比べて、どういう効果があるかちょっと考えてみる。

    • 規模

      CPI 自体の規模は非常に小さい。CPI だけを使うと ほぼ 2 倍の規模になると見積もれる。

      一方 SMP 化で共用するのは、ROM/RAM/装置IOR(PORT/SPI/USART)

      ROM/RAM はブロックRAM で単に使用個数の問題。SMP だと いわゆる分割損の分節約できるかも知れない。ただ、すなおに Dual Port の機能を使っていたのが、(CPU から見て)Single Port 化 することになり規模的にはセレクタの分が少々増える。

      IOR には、プロセッサ固有のものがある (SREG/SP/TMR0/CPI0)。これらは、単純に 2 倍になるから CPI だけの場合と比べて違いはない。

      装置IOR(PORT/SPI/USART)だけは、1 つしか持たない。これらは SMP の方が有利そうに思えるが、調停機構や、それぞれの CPU からのアクセスができるようにする配線で相殺されそうなかんじ。

      まぁ SMP だからといって有利にも不利にもならないように思える。

    • 扱いやすさ

      rtavr 同士で通信するなら、整合性がとれたプログラムが 2 つ必要だ。SMP なら 1 つなのだ。プログラミングには、少々コツがあるが、SMP の方が扱いやすい。

      構成についても同じ。SMP でなければ、2 種類を構成し、プログラムも別々に定義しないといけない。ー 実をいうと 今の rtavr は、2 種類を Implement することを想定しておらず、それ自体を行うためにいろいろ面倒なことをしないといけない。

    • 性能

      そもそも 2 個付けるのは、性能のためである。で、SMP はどう有利なのだろう?

      SMP では、CPI を相互に接続するから、不利な点はない。初期化以降 CPI だけを使って通信するなら、CPI だけのときと等価の動作も可能だ。

      ある装置から収集したデータを加工して もうひとつの CPU に送り込み、そこでさらに加工して出力する場合を考えてみる。

      こういう単純な通信しかしないのであれば、CPI を使うだけで事足りる。FIFO に送り込んだりするなら、ポインタの管理が不要な分高速にすらできる。

      性能的に有利になるとすれば、バッファが 16段の FIFO で足りない場合か、マルチストリームが必要な場合。
      ... といっても 細工すれば、バッファは増やせる。64段程度ぐらいまでなら対応できそうだ。マルチストリームも CPI を 増設する方法がある。2 個 3 個ぐらいならなんとかなる。規模には限界があるが、そもそもプログラムの規模が増えると rtavr に入らない。

      ランダムアクセスが必要な場合は、SMP が圧倒的に楽だ。CPI だとプロトコルを組んでいろいろ検討しないといけない。... といっても ランダムアクセスといえるだけのデータ量はそもそも扱えない。

      やはり、SMP だからといって性能は特別有利とは思えない。-- SMPの特徴は柔軟性だと言えそうだ。プログラムを変えることでいろんなやり方ができる。


対応状況(その2)


    // Target Device: xc3s200a-4ft256 , top-level rtavr
    // 従来 ior 新 ior
    // Number of Slice Flip Flops: 390 390
    // Number of 4 input LUTs: 1176 1081
    // Number of occupied Slices: 652 654
    // Number used as a route-thru: 33 33
    // Number used for Dual Port RAMs: 16 16
    // Number used as Shift registers: - -
    // Number of bonded IOBs: 12 12
    // IOB Flip Flops 1 1
    // Number of BUFGMUXs 3 3
    // Number of RAMB16BWEs - -
    // Number of DCMs - -
    // Number of BSCANs - -
    // Post-PAR Static Timing Report
    // Maximum frequency(MHz): 43.894 44.715

    とりあえずは、rtavr_ior.v のかわりに rtavr_ior_ms.v/rtavr_ior_ps.v を使って Implement できるようになった。50A 用の Config ではわずかに +2 スライスの増加で済んでいる。


    // SHRINKED SMALL-SP SMALL-SMP
    // Number of Slice Flip Flops: 390 421 732 (+ 342)
    // Number of 4 input LUTs: 1081 1198 2268 (+1070)
    // Number of occupied Slices: 654 727 1341 (+ 614)
    // Number used as a route-thru: 33 33 61
    // Number used for Dual Port RAMs: 16 16 32
    // Number used as 16x1 RAM: - 8 8
    // Number used as Shift registers: - - 16
    // Number of bonded IOBs: 12 12 12
    // IOB Flip Flops - - -
    // Number of BUFGMUXs 1 1 1
    // Number of RAMB16BWEs 3 3 3
    // Number of DCMs - - -
    // Number of BSCANs - - -
    // Post-PAR Static Timing Report
    // Maximum frequency(MHz): 44.715 45.319 46.134
    //
    // SHRINKED : soc/configs/50A/rtavr_defs.v
    // SMALL-SP : smp/configs/small-sp/rtavr_defs.v
    // SHRINKED + ROM_PSEUDO_DP + SUPPORT_LOCKING + IOR_HAVE_GPIOR
    // + IOR_HAVE_RAMWIN + IOR_HAVE_RAMWIN_HA + NVM_RAM_PROTECT
    // SMALL-SMP : smp/configs/small-sp/rtavr_defs.v

    SMP が Implement できるようになった。SHRINKED は、上記 新IOR に ROM を共通化した rtavr_rom_p4.v を使ったもの。これに、SMP で使う機能を加えたのが SMALL-SP 。SMALL-SMP はそれを SMP 化したもので、top-level として rtavr_smp.v を追加(他のソースコードは共通)。CPU 間通信用の CPI0 も入っている。

      現状、多数の Warning が出ている。直していくと多少規模が増えるかも。

    これに、IOR の調停機構を入れて、ひとまず完成のつもり。

    ところで、SMP のテストは、悩ましい。タイミングで動作が変わるからシミュレータとのトレース比較ができないのだ。ただ、動作が変わらないコードを書いて、それぞれの CPU の トレースを比較することはできそう。

愕然となった事実

    いろいろ見直してたら、いろんな所で RESET == 0 のとき、リセット動作をしているのに気がついた。... ずっと RESET は正論理 -- 1 でリセットのつもりだったのだ。で、現状は、正論理と負論理が混在。

    良く動いていたものだ。もともと正論理のつもりなので、それに合わせて修正。テストベンチも変更。

IOR の調停(の準備)

    GPIOR は、SMP で CBI/SBI が自由にできるように導入したのだが、分散メモリだと 調停するのが面倒なことになる。結局、構成を自由に変えられることにして FF で作り直した。これで、アドレス単位で調停すれば良いことになる。

      GPIOR0 - GPIOR2 の 3 つを構成すると 654 スライスが 681 スライスになった。SP(Single Processor)でこれだから、SMP だと もっと増えそうだ。

    あと、アドレス単位での調停をしたいのは PORT と RAMWIN の RAMDR 。

      PORT には、複数の装置が割り当てられているので、調停なしだと、ソフトで排他制御してアクセスすることになる。ビット出力するにもロックしてからとなると、非効率どころではない。

      RAMDR は、排他制御をできるようにするためのカナメだから、調停は必須。

    PORT も インターフェイスを変更して DDR と PORT を同時に書けるようにした。

    (調停機能の定義)以上のレジスタは、アドレスが同じなら 同時にアクセスできないようにする。

      RAMDR を除く CPU 固有のレジスタは、調停が必要ない。それ以外のレジスタも調停しないことにする。 ひとつのサブモジュールに対して同時に更新すると誤動作するので、ソフトでの排他制御が必要になる。サプモジュール毎にアクセスする CPU を決める使い方ならソフトでの排他制御は必要ない。

愕然となった事実(2)

    RAMWIN は、0x1f の RAMDR に対して SBI/CBI することができる。要するに RAM に read-modfy-write の機能が必要だということだ。

    実際にテストしてみて初めて気がついた。幸い ROM/RAM を 1 クロックの 前半 READ / 後半 WRITE と 2 回アクセスできる仕組みを以前使っていたので対応できた。ただ、IOR は非同期 READ を前提にしていてラッチしている。RAM の READ は間に合わないので、RAMWINからの READ は、ラッチを通さずセレクタで切り替えることにした。

    だが、ちゃんと対応しても動かない。変だと思って調べたら 直前の SBIS/SBIC 命令でおかしなことをしていた。... 原因はデコードのバグ。

    ... RESET もそうだが、今に至ってこのレベルのバグがみつかるとは!

    ちょっと不安になってきた。

rtavr-0.9.0

  • rtavr-0.9.0.tar.gz

    なんだかんだで、まだまだという気はするが、ついに 0.9.0 にした。

    ファイルを整理して、中途半端ながら ドキュメントも付けた。

    avr8l_trace の機能を追加。(ドキュメントはできていない)

      GPIOR0/GPIOR1 を付け、 RAMWIN の仕様を現状に合わせた。

      さらに、SBI/CBI 命令の仕様を変更。

      -exbi を付けると、CBI/SBI で変更するビットの変更前の値を T レジスタに入れる。

      ... こうすると TEST & SET の機能になる。GPIOR0/GPIOR1 などを 1bit 単位で ロック変数にできるのだ。

    もちろん rtavr での機能も実装。(SUPPORT_EXBI) 。tests/tbi_001 でコードを入れて確認済み。


    000004c2 <t_test_and_set>:
    261: 2788 eor r24, r24
    262: 9a1f sbi 0x03, 7 ; 3
    263: f980 bld r24, 0
    264: fb81 bst r24, 1
    265: 9508 ret

    テストコードは、こんな風にした。sbi で GPIOR bit7 に 1 を入れる。old-value が T に入るから 戻り値の bit0 に移す。バグったときトレースの差分が沢山出ないように T を bst でクリア。

    で、結果が 0 なら old-value が 0 だったということだからロック成功。1 なら失敗。

    あと RAMWIN のテストコードも紹介しておくと..

    000004ae <t_lock>:
    257: e744 ldi r20, 0x74 ; 116
    258: e050 ldi r21, 0x00 ; 0
    259: bb5e out 0x1e, r21 ; 30
    25a: bd40 out 0x20, r20 ; 32
    25b: 9bff sbis 0x1f, 7 ; 31
    25c: bb8f out 0x1f, r24 ; 31
    25d: b38f in r24, 0x1f ; 31
    25e: 9508 ret

    まず、アドレスを 0x0074(char lock) に設定。lock の MSB が 0 なら 第一引数(val: 0x80 とか)をout 。
    改めて in で READ して同じ値なら ロック成功。

    CBI/SBI の仕様変更が嫌ならこのやりかたをする。

      bst/bld なんて滅多に使わないからチェックは楽なんだが、互換性がないと困る場合もあるかも知れない。命令を新設するのはやりたくないので、互換性を維持してロックを作れる この方法もサポートする。

    これらは、0.9.0 の tbi_001 に入れてある。


SMP を『Icarus Verilog』で 確認



    ちょっと修正が必要だったのだが、『Icarus Verilog』で 確認できるようになった。

    基本的に rtavr と rtavr_smp の インターフェイスは同じにしている。わずかな修正で 従来のテストベンチを使えるようにできた。

    動かしてみると ... 当然と言えば当然なのだが、IORの調停が必要にならない限り CPU0 と CPU1 は 全く同じタイミングで動作する。そして、CPU_ID が入っている NVMCSR 以外のデータは全く同一で、同一データに対する結果も同じ。

    tb_shuffle や tb_queen は、コアテスト用なので IOR にアクセスしていない。当然ながら CPU0 と CPU1 は、最後まで同じ動作をする。

      ちなみに、トレースを取るのは、CPU0 だけだが、define PRC_WATCH_P1 とすると CPU1 だけを取るように変わる(未確認)。avr8l_trace も対応していて、-1 オプションを付けると、CPU_ID の値を 1 にする。(ただし、CPU0 と CPU1 で協調動作した場合のトレースは無理。)

    tbi_001 はロック命令のテストコードがあるので、CPU0 と CPU1 とで違う動作になった。

      BB5E は、0x1e (RAMARH) に対する OUT 命令で、BD40 は、0x20(RAMAR) に対する OUT 命令。0x1e に対しては調停の要求が出て 0x20 に対しては 要求が出ない。-- これは S0 のPRE命令デコードで決めている。

      この競合で勝つのは、lk_last でない方。-- lk_last の初期値を 1 にして CPU0 を勝たせている 。

      負けた CPU1 は 1 CLK ずれる。

      9BFF は、SBIS 命令で、次が同じアドレスに対する OUT 命令なので、2 クロック分を要求する。1 CLK 遅れた CPU1 はまた負けるのだ。

      結構良いところまで行っているのだが、バグっている。-- 負けた側が 2 回目の REQ を出していない。

      よくよく見れば、負けた側が 次の命令にいってしまっている。S1 での判定にしたが、引き伸ばせるのは、S0 だけで S1 に入ってしまったら、キャンセルすることしかできない。S0 で調停して負けたら そこで引き延ばさないとだめだ。-- 全然ダメのように見えるかも知れないが、コード量は少ないし、確認できるわけだから実は大した事はない。



      直してみた。それ自体は簡単だったのだが、ROM_PSEUDO_DP のコードを入れたときに ROM データを CLK_180 でラッチしていたのだった。そのため、判定で使える期間が 1/4 CLK になってしまっていた。これでは ボトルネックになりそうなので、ROM のタイミングを変更。

        ROM は CLK_0 で アドレスを出しておいて CLk_90 で 読み込み。データが安定するのはそれ以降だから CLK_180 でラッチしていた。なぜそれが必要だったかというと、ROM を書き換える場合 CLK_180 で 再度アクセスして、そのときに 出力データが変わってしまうため。命令データは、CLK_0 まで変化してはいけないのだ。

        で、正しい解決方法は良くわからない。とりあえず、CLk_180 で読み出しデータと ラッチデータをセレクタで 切り替えるようにしてみたが、正しい解決方法のような気がしない。まだレベルセンシティブ・ラッチの方がましかも知れない。

    • rtavr-0.9.1.tar.gz

      ... ここまで書いてコードも提示しないのは、どうかとも思うので 0.9.1 にした。.. これから 0.9.x の x をどんどん上げていく。

        0.9.1 では、rtavr_rom_4p.v は、セレクタ方式だが、次から レベルセンシティブ・ラッチに変更する。(セレクタ方式もとりあえずは残す) 。ちなみに 両方とも ROM_PSEUDO_DPにしたときの規模の増加は同じで、+ 26 スライス。

      0.9.1 での重要な修正はまだある。CBI/SBI の仕様を変更したものを default にしたこと。これで、互換コアと言いづらくなった。(互換モードは残しておくので、互換だと言い張るつもりだが)

Ver. 0.9.2

  • rtavr-0.9.2.tar.gz

    0.9.2 を置いた。

    変更点は、rtavr_rom_4p.v を レベルセンシティブ・ラッチに変更したぐらい。

    あとは、rtavr_defs.v の見直し。RTAVR_SMP を導入し、SMP の設定を楽にするのが目的。この変更ではじめて `undef を使った。

    ついでに、RTAVR_TARGET_MachXO2 を導入。いくつかの項目をチェックして自動で define する。Lattice MachXO2 に対応できているわけではなく、本体でも参照しない rtavr_defs.v の中だけの定義。ーまだまだ準備といったところ。

    それより、scripts/unifdef.awk の追加と doc/TOOLS-j.txt の追加がメイン。 unifdef.awk は、ifdef を展開して、ひとつの Verilog ファイルを作るのが目的。 どのコードが実際有効なのか、よくわからなくなった時に使うのが目的だが、一応ちゃんと Implement できるから、これを使って Implement しても OK 。複数のファイルを remove → add するより便利かも。

    あとソースの規模の見積もり。全体で 8118 行もあるが、50A 用の config なら、実際に使われるのは、3902 行というのが分かる。ほとんどの機能を ON したはずの large でも、4606 行。large-smp でようやく 5497 行。

    追記) scripts/unifdef.awk はバグっていたので修正: あと、debug 用出力も可能にしておいた。次で修正版にする。

そろそろ

    実際に動かすことをメインにしていこうと思う。
    ツールつくるの面倒なので、SMP とか 論理設計に走ってしまったが、もう十分堪能した。
    発注しなおした基板も到着したし、いいかげん作りだそう。

Ver. 0.9.3

  • rtavr-0.9.3.tar.gz

    0.9.3 を置いた。これで当面凍結。

    変更点は、rtavr_defs.v から rtavr_common.v を分離して、config/ に置いたことと、トップディレクトリに Makefile を置いて unifdef.awk でひとつにまとめた ソースを生成できるようにしたこと。

    バグ修正は、unifdef.awk と ROM_PSEUDO_DP のラッチ版。一応 tests での make で結果が一致する状態になっている。

    まだあった。MachXO2 版の準備。xo2_sample で JTAG と接続するようにしておいた。

(次はツール編)
posted by すz at 12:40| Comment(0) | TrackBack(0) | AVR_CORE

2011年05月20日

AVR互換コア(FIFOモジュール)

少し大きめの FPGA なら AVR互換コア(rtavr) を複数インプリメントできる。

その時に、rtavr 同士が通信できるモジュールとして FIFO モジュールを検討してみた。

    突然こういうことをやり出したのには、理由がある。それについては別記事にする。

    FIFO モジュールの説明は、

  • XAPP256

    に書いてあるのだが、このインターフェイスを参考に 一般の Verilog で記述してみた。

    実装方式として、Dual Port 分散RAM による方式(以下 DPORT) と シフトレジスタによる方式(以下 SHIFT) の 2 つを考えた。

    DPORT 方式は、Dual Port 分散RAM をサポートしている FPGA なら素直に記述すれば、推論してくれるはず。SHIFT 方式は、generate を使って二重ループという .. なんだか複雑な記述になってしまった。成功すれば、DPORT 方式より コンパクトになるが、失敗すると 全部 FF にされて 規模が増えてしまう。



これは、シミュレーション結果。


// Target Device: xc3s200a-4ft256
// Product Version: ISE 12.4
// Design Goal: Balanced
// SHIFT DPORT
// Number of Slice Flip Flops: 12 19
// Number of 4 input LUTs: 20 39
// Number used as Shift registers: 8 -
// Number used for Dual Port RAMs: - 16
// Number of occupied Slices: 14 26
// Number of bonded IOBs: 26 26
// Number of BUFGMUXs: 1 1
// Post-PAR Static Timing Report
// Maximum frequency(MHz): 114.077 125.691
//

SHIFT 方式だと、14 スライスで済んだ。

    最初に作ったのは、9 スライスだったのだが、COUNT 出力を付けたりして使いやすい仕様にした結果 + 5 スライス増えた。
    SHIFT 方式について肝心な部分だけ転載すると ..

    assign OUT = r_out;
    assign EMPTY = ( r_pos == 4'hf );
    assign FULL = ( r_pos == 4'he );
    wire [3:0] fifo_count = r_pos + 1;
    assign COUNT = fifo_count;
    always @(posedge CLK)
    begin
    if (CLR) r_pos <= 4'hf;
    else
    begin
    if (WR & RD)
    begin
    end
    else if (RD)
    begin
    if (~EMPTY) r_pos <= r_pos - 4'h1;
    end
    else if (WR)
    begin
    if (~FULL) r_pos <= r_pos + 4'h1;
    end
    end
    end
    always @(negedge CLK)
    begin
    if (~EMPTY) r_out <= fifo[r_pos];
    end

    generate
    genvar i,j;
    for (i=0; i<WIDTH; i = i+1)
    begin : data_in
    for (j=1; j<16; j = j+1)
    begin : data_in_bit
    always @(posedge CLK)
    begin
    if (WR) fifo [j][i] <= fifo[j-1][i];
    end
    end
    always @(posedge CLK)
    begin
    if (WR) fifo [0][i] <= IN[i];
    end
    end
    endgenerate

    なにはともあれ、これはうまくいった。


さて、これを使った、AVR のモジュールの仕様を考えてみる。

    まず、レジスタや 割り込みをあまり使いたくないという事情がある。空きが少なくて 厳しいのだ。それに複数付けたくなるかも知れない。最低限のリソースで済むようにしないと。

    次に、機能は送受信。相手も同じモジュールを使う。で、FIFO をどちら側に付けるか --これは送信側ということにする。

  • 割り込み

    USART などは、3 種類も割り込みを使っている。が、これを 1 つで済ます。

    割り込みの意味は、NOTIFY で CPU で IOR に書きこんで発生させる。割り込みを受けた側が スタータスを見てなにをすべきか判断する。

    割り込み許可のフラグも必要だから、レジスタを 2 bit 使う。

  • データレジスタ

    これは、USART の UDR のようにREAD すれば受信データが読めて、WRITE すれば送信データを 書きこむ ことにすれば良さそうだ。

  • ステータス

      受信データがある
      送信中(相手が全部を受け取っていない)
      送信が可能(空きがある)

    これぐらいは必要そうだ。これで、合計 5 bit 。

    あと、送信バッファがどれぐらい空いているのか も知りたい。送信中フラグ と 送信可能フラグをやめて 4 bit の情報にしよう。-- この変更で 合計 7 bit 。

  • コントロール

      送信データの破棄
      NOTIFY 割り込みの送出

    ぐらい? あと、NOTIFY 割り込みを相手が受け取ったかどうかの情報が欲しい。これはステータスに入れる。

さて、こんな仕様などより悩ましいのは、名前。-- 名前を付けないとファイルも作れない。何にしよう。

    機能的には、通信ポート。... CPI(Communication Port Interface) ということにして、モジュール名は rtavr_ior_cpi 。

    あとはなんでもかんでも CP を付ける。

    レジスタ名は、CPCSR (CP Control and Status Register) , CPDR (CP Data Register)

    フラグ名は沢山ある。

    Communication Port Interface(CPI):

    +-------+-------+-------+-------+-------+-------+-------+-------+
    0x09 | CPIR | CPIE | CPIS | CPRXS | CPTXS     |
    +-------+-------+-------+-------+-------+-------+-------+-------+

    +-------+-------+-------+-------+-------+-------+-------+-------+
    0x0a | CPDR |
    +-------+-------+-------+-------+-------+-------+-------+-------+

    CPIR : CP Interrupt Recv. Flag
    CPIE : CP Interrupt Enable Flag
    CPIS : CP Interrupt Send Flag
    CPRXS : CP Recv. Status (1: Recieved)
    CPTXS : CP Trans. Status (xxx0 : Empty , 1xxx : Full )

    こんな感じか。CPTXS は ちょっと細工。2bit で 詰まり具合が分かるようにする。

    Control の方は

    • CPTXS[0] に 1 を書くと バッファを破棄。
    • CPIS に 1 を書くと 割り込みを送出して、受け取られたら 0 に戻る。
    • CPIR / CPIE は、AVR のほかの装置と同じようにする。(詳細未定)


実装完了

    // Target Device: xc3s200a-4ft256 , top-level rtavr
    // SHRINKED DPORT SHIFT
    // Number of Slice Flip Flops: 388 407 403
    // Number of 4 input LUTs: 1089 1173 1162
    // Number of occupied Slices: 662 710 699
    // Number used as a route-thru: 34 35 35
    // Number used for Dual Port RAMs: 16 32 16
    // Number used as Shift registers: - - 8
    // Number of bonded IOBs: 12 36 36
    // IOB Flip Flops - - -
    // Number of BUFGMUXs 1 1 1
    // Number of RAMB16BWEs 3 3 3
    // Number of DCMs - - -
    // Number of BSCANs - - -
    // Post-PAR Static Timing Report
    // Maximum frequency(MHz): 46.198 43.459 42.531


    SHIFT で +37 スライス / DPORT で +48 スライス。

    output [7:0] CPI0_TXD : 送信データ
    output CPI0_TX : 送信データあり
    input CPI0_TX_ACK : 送信データあり ACK
    output CPI0_IXS : 割り込み送信
    input CPI0_IXS_ACK : 割り込み送信 ACK

    input [7:0] CPI0_RXD : 受信データ
    input CPI0_RX : 受信データあり
    output CPI0_RX_ACK : 受信データあり ACK
    input CPI0_IXR : 割り込み受信
    output CPI0_IXR_ACK : 割り込み受信 ACK

    信号線は、こんな風に定義した。クロックは共有しているのが前提。
    送信/受信は、対称になっていて、上と下をたすきがけ(クロス)で接続する。

    データそのもの以外の信号線は、全部ハンドシェークする。ACK は、posedge_CLK_180 で受け取り。

    規模は小さいのだが、rtavr に組み込むのは、ものすごく面倒だった。
    組み込み方法が 多数あるので、それに対応しないといけないし、接続用の信号も rtavr_fifo - rtavr_ior_cpi - rtavr_ior - rtavr と 3 段もパススルーしないといけない。

    それは、ともかく ... これでプロセッサ間通信のしくみが確立できた。次の記事『AVR互換コア(SMP化)』に続く。
posted by すz at 23:32| Comment(0) | TrackBack(0) | AVR_CORE