2011年01月04日

AE-UM232Rピン互換ボード

Teensy(1.0)互換ボード』を作ってみたわけだが、秋月 の arduino もどき AE-ATmega が出たのを知り、AE-UM232R ピン互換にすれば良かったと思ってしまった。

配線が難しいので、Teensy(1.0)互換ボードのようには作れないと思いつつ、作ってみることにした。案の定 LED も レギュレータさえ入らなかったのだが、なにやらそれらしいものが出来た。



出来がったのはこんなやつ。いろいろ外していったが、ブートローダを起動するためのリセットボタンだけは外せない。



回路図は、こうなった。AE-UM232R とどこが ピン互換かについて説明していこうと思う。

その前に、ターゲットは、AE-ATmega ( と eJackino ) だけである。完全な互換性など目指していない。むしろ 組み込んだときに UNO 互換になるように考慮している。

    UNO 互換になるかどうかは、まだ考察不足。これからまじめに考えようかと思う。

ピン配置

    TXD o PD3(TXD) GND o GND
    DTR o PD7 PD5 o CB0 TX_LED
    RTS x PD6 PD4 o CB1 RX_LED
    VIO x VCC N.C.x VCC
    RXD o PD2 RST o RST ( - VCC)
    RI o PB0(SS) UCAP o 3V3
    GND o GND PD1 x CB3
    DSR o PB1(SLCK) PD0 x PU1
    DCD o PB2(MOSI) PC2 x PU2
    CTS o PB3(MISO) N.C. o VCC
    CB4 x PC5 UVCC o USB
    CB2 x PC4 GND o SLD ( - GND)

    J1:
    1 UCAP (3.3V出力)
    2 VCC
    3 UVCC (5v 出力)


このように割り当てた。外側は、AE-UM232R の信号名。o/x はAE-ATmega ( と eJackino )での接続の有無。

  • 電源関係

    AE-UM232R は、J1 の設定で、5V I/O と 3.3V I/O を切り替えられる。AT90USB162 は、UCAP に 3.3V 出力が出ているので、VCC を USB VBUS と UCAP のどちらかから選ぶということにした。AE-UM232R は、I/O だけを切り替えられて 1.8V までの範囲を選べるがさすがにそれは無理。また、VCC と VIO が別になっているが、VIO を VCC に読み替え、AE-UM232R の VCC は N.C. とすることにした。

  • リセット

    リセットは、すなおに RST に接続している。ターゲットは、AE-ATmega ( と eJackino ) といいながら、これだと具合が悪い。だが、外部から ISP で書きこむためには RST を出しておかないといけないので、このようにした。

  • シリアル

    使っているのは、TXD , RXD, DTR だけ。信号線以外だと TX_LED / RX_LED がある。
    これらは、UNO と同じ信号線を選んでいる。

    ただ、AE-ATmega ( と eJackino ) とつなげたときに 不具合がないかどうかについて、ちゃんとは考察できていない。特に DTR は、HWB の機能も兼ねる PD7 を使用していて少々不安。

  • X3 コネクタ

    ここは、Bitbang ライタ用と割りきって 同じ割り当てになるよう SS/SLCK/MOSI/MISO を割り当てた。

  • その他の信号線。

    無接続の RTS , CB4 , CB2 , PU2 , PU3 , CB3 については、配線の都合が良いものを選んで割り当てた。
    割り当てたピンのうち PWM が可能なのは、PC5 の OC1B と PD0 の OC0B 。

EAGLEファイルなど

  • um162-01.zip (全部入り)
  • um162-01-out.zip (Fusion PCB 提出用)

    上で説明したように、問題があるが提示しておく。もう少し検証してから 発注しようと思う。

自作ファームウェア

    Teensy(1.0)互換ボード』の記事で説明しているので、ここでは詳しく書かない。USBasp 互換 ブートローダや USBasp 互換ライタは用意できている。シリアルを UNO 互換として使うには、DTR サポートが必要なので、未だこれから。

    UNO 互換になるなら 自作ファームウェアで全部揃える必要などないし、LUFA という手もある。だが、だいぶ基本は揃っているし、できる範囲で対応していこうと思う。

追記:出来上がった



    #15 VCC端子は、ジャンパで VCC に接続。RESET の横の PORT を RESET に接続。LED も なんとか入った。もう触りたくない。これで行くか。(行った: 発注済)

    回路図:


    検討内容

    • VCCピン の扱い
      AE-UM232R には、VCCピン と VIOピン がある。3.3V と 5V を切り替えて VCC に入力できるようにしたが、それだと VIOピン = (AT90USB162 の)VCCと定義しないとならない。VCCピン は N.C. と定義したが、それだと AE-ATmega に合わない。#15 の VCCピン と VIOピン を ジャンパ(J2)できるように修正して 対応することにした。

    • RSTピン
      AT90USB162 の RESETを RSTピンに割り当てたいのだが、AE-ATmega では、RSTピンを 5V に直結している。これだと リセットボタン(ブートローダ起動ボタンと定義)が効かない。どうしたものかと思ったが、UNO でも ブートローダ起動には面倒なことをしなければならないことが分かった。

      リセットボタンでブートローダを起動したいならば、AE-ATmega の RSTピン のところをパターンカットした上で R5 を付ける と割り切ることにした。

    • HWB をプルダウンして問題ないか?
      AE-ATmega の RSTピンをパターンカットしないなら、外部電源 ON で VCC と リセットが同時に立ち上がる。このときに ブートローダは外部リセットだと認識はしないはず。その場合 HWB = PD7 の値は不定でかまわない。だから R5 を付けても問題ない。ただし、J1 をオープンにしないと 外部リセットになるはずで、R5 を付けたらブートローダが起動されてしまう。R5 を付けないと大丈夫かというと 微妙。コンデンサが付いているから、前の DTR (= PD7 = HWB) が保持される。外部電源 ON の条件だから 多分 ブートローダ起動になると思う。

      逆にRSTピンをパターンカットした場合、J1 をオープンにしておけば外部電源 ONで普通にパワーオンリセットになる。その場合ブートローダは起動しない。J1 をオープンにしないと外部電源 ON は関係なくなる。だが、普通に USB が接続されているだけだから問題は起きないはず。もし USB を再接続したい場合があったら USB ケーブルを抜き差しする。

      というわけで、問題ないだろうという結論にした。

    • LED
      ボード上に LED をひとつでも付けたかったのだが、やりくりしてなんとか付けることが出来た。

    • アプリケーションからの ブートローダ起動
      ちょっと実験的に RESET のとなりのポート(PC6) をRESET に接続してみた。

      AE-ATmega では、DTR (= PD7 = HWB) に コンデンサしかつながっていない。R5 を 付けなければ HWB の値は 保持される(はず)。だから DTR を設定して PC6 を L にすれば、ブートローダ起動するか アプリケーションを再起動するか選べるはず。ちなみにUNO では R5 に相当するパターンはあるがなにも付いていない。

        (1) ( AE-ATmega の RSTをパターンカット) + ( R5 を付けない ) + (J1 オープン) とするとほぼ(※) UNO と同じになる。
        (2) R5 を付ければ、リセットボタンで ブートローダ起動できるようになる。(UNO で同じことをするには、外部にリセットボタンが必要)
        (3) さらに PC6 を L にする機能を使えれば、アプリケーションからの ブートローダ起動も可能になる

      というわけだ。

      まだコードを組んでいないのだが、なにかおまじないをすることで PC6 を L にして リセットをかけるようにしようかと思っている。

      (※) UNO と違うのは、AE-ATmega のボード側。UNO は、外部電源自動切り替え。AE-ATmega は、ジャンパピンによる設定。だから同じにはならない。むしろ (J1 = 5V) 設定にした方が UM162 から見た動作は UNO に近いかも知れない。

      参考資料

    EAGLEファイル:
  • um162-03.zip (全部入り)
  • um162-03-out.zip (Fusion PCB 提出用)

    VIA に対して Stop On 設定をした。(参考)

      Fusion PCB では、eagle のデフォルトだと VIA もレジストで マスクしてしまう。いままで作った基板は全部デフォルト。要注意。

      なぜそうするとまずいのか 実はよく知らないが いままで発注した P板.com や EzPCB は全部 レジストしないように向こうで修正してくれている。-- Fusion PCB ではそれをしてくれない。しかも VIAの中のレジストは乾いていないようだ。熱を加えると焦げる。

    (実際に発注した基板)
  • um162-02.zip (全部入り)
  • um162-02-out.zip (Fusion PCB 提出用)

      um162-02-out.zipを送れば良いだけなので、eagle を使えない人でもこのボードを作ることができる。ちゃんとライセンスを書いてないが、GPL に準じようと思う。要するに um162-02-out.zip の生成物であるボードを売ったり配ったりするなら それを作った eagle ファイルの (ボードを受け取る人への)提示が必要。改変も OK 。

      ちなみに、著作権はデザイン -- すなわち基板のアートワークにも適用されるが、それに対して著作権は主張しない。この eagle ファイルを使わずに使ったものに関しては関知しないということ。

      注意) 上記の記述は私の著作権に関する宣言で、実際に商用利用するとなると Eagle のライセンスが必要になる。最低でも 商業利用登録をした Light Edition が必要になるようだ。→ 購入先 : サーキットボードサービス

    ピン配置(あらためて記載)



      TXD (1) PD3(TXD) GND (24) GND
      DTR (2) PD7 PD5 (23) CB0 TX_LED
      RTS (3) PD6 PD4 (22) CB1 RX_LED
      VIO (4) VCC N.C.(21) VCC
      RXD (5) PD2(RXD) RST (20) RST
      RI (6) PB0(SS) UCAP (19) 3V3
      GND (7) GND PD1 (18) CB3
      DSR (8) PB1(SCLK) (OC0B)PD0 (17) PU1
      DCD (9) PB2(MOSI) PC2 (16) PU2
      CTS (10) PB3(MISO) VCC2 (15) VCC
      CB4 (11) PC5(OC1B) VBUS (14) USB
      CB2 (12) PC4 GND (13) SLD(GND)

      (ピン番号の外側は AE-UM232R の名称)

      J1:
      (1) UCAP (3.3V 出力)
      (2) VCC
      (3) VBUS (5v 出力)

      (補足)
      VCC2は J2 ジャンパで VCC と 接続
      RESET と PC6 を接続: (ブートローダ起動用)
      PB4 を LED に接続 (L で点灯)


    パーツリスト
  • ATMEGA32U2 は、デジキーで 単価 410円で入手できる。国内だと マイクロファンで 単価 630円 -- 数を買わないなら こちらの方が良いかも。AT90USB162/ATMEGA16U2 の入手は実は難しい。

    U1 AT90USB162/ATMEGA16U2(/ATMEGA32U2) TQFP-32 ( 0.8mm ピッチ)
    D1 秋月 1608タイプLED
    X1 16MHz 秋月 FA238

    R1,R2 22 SMD 2012/1608 (USB 用: 47 でも動作するかも)
    R3 1K SMD 2012/1608 (LED 電流制限用)
    R5 10K SMD 2012/1608 (HWB 用プルダウン)
    R6 1K SMD 2012/1608 (リセット用 330 - 1K ぐらい)

    C1 10u SMD 2012 (秋月 10u)
    C3 1u SMD 1608 (秋月 1u)
    C4,C5 22p SMD 2012 (マルツ、千石とか)
    (または 10p /10p x2 (秋月 3216 10p)
    SW1 秋月 TSKB-2JL,LS6J2M-T
    CN3 秋月 UX60A-MB-5ST USB miniB


    秋月 の arduino もどき AE-ATmegaと接続する際の注意点:
  • J1 は オープン
  • J2 を接続するか、AE-ATmega 上で #15 と #4 を接続
  • AE-ATmegaの RST端子(#20) を パターンカットする。(しないとボタンが効かない)

    Fusion PCB の記録

      価格: $20 + $3.52 (85円換算で ほぼ 1999円)
      01/04 発注
      01/10 完成?
      01/11 送付 (RTxxxxxxxxxHK)

      SG から HK に切り替えたようだ。いつ到着するのだろう? 


    angel_loader - usbasp2 ピン配置(案)



    未だ完成していないが、ISP に加えて TPI/PDI をサポートしようとしている。(DIR) と書いてあるのは、バッファ制御用(ロジアナデバッグ用) で 受信中は H 送信中は L の出力をする。

    それに加えて ISP 使用中にクロックを出力しようかと思う。これは水晶入力にしてしまった AVR の救済用で XTAL1 に クロックを接続することで 書き込みできるようになる。

    ちなみに、LED は TX_LED = 赤 / RX_LED = 緑 のイメージで 制御するつもり。usbasp2 モードで立ち上がると 赤が点灯。avrdude で接続し RESET を L にすると 緑が点灯。実際に ISP しているときは、赤を消灯 (点滅する) 。
    本体 LED は、TX_LED の逆論理で制御する。

    追記: よくよく考えたのだが、通常のシリアル ファームウェアに serjtag を載せようと思う。切り替えは DTR 。普通 DTR = 1(API 上: 実際は L レベル) にして シリアルの通信を行う。( avrdude の arduino も DTR = 1 で通信している。)

    DTR = 0 での通信は serjtag に切り替えることにすると、通常の通信と プログラミングモードを 両立できる。

    ちなみに、avrdude の serjtag は デフォルトを使っているが、この状態は DTR = 0 ということらしい。( ちなみに Linux/MAC 版では ser_posix の 設定関数 serial_set_dtr_rts の 論理が逆になっていてバグっている )

    そういう風にしておいて、serjtag をちゃんとサポートしようと思う。

追記: AE-ATmega 入手。



とりあえず RST をパターンカットして記念撮影。(IC ソケットを付けた後では加工できないので注意)
表面がすべるので、刃物を使わずに 三角やすり(not ダイアモンドやすり)で カットしてみた。

追記: arduino UNO SMD なるものが出たらしい。



互換ボードを作っているので、気になる。問題は ISP 横の 4 つの スルーホール。たぶん X3 コネクタの代替。
PB0-PB3 なら嬉しいのだが、多分違う。基板もできていないうちに、(将来の)互換性がなくなるとは ... トホホな気分。でも、まぁいいや PB0-PB3 だけが SPI で正統だし、UNO そのものとは互換のはずだし。おまけのピン割り当てが違うだけ。知らないことにしておこう。
posted by すz at 06:25| Comment(80) | TrackBack(0) | USB162

2010年12月04日

Teensy(1.0)互換ボード 製作編

Fusion PCB で作ってもらったボードが届いたので早速作ることにした。実をいうと写真を取りながら作ってたのだが、ピントが部品にあってなくてピンボケばかりだった。使える写真は残念なことに少ない。
この記事は、『Teensy(1.0)互換ボード』の記事の製作編。重複して説明しないので、メインの記事を参照のこと。



まずは、表の部品をだいたい載せたところ。

  • 今回は、マスキングテープで箱に貼り付けて作ることにした。

  • MCU は、ATmega32u2 にした。あと LED は 2個入りの SEC2492 にした。オレンジ/緑のやつで 秋月の SEC2764C とは色とレンズが違う。これを (補修せずに)回路図どおりの向きでつけた。互換ボードといいながら いきなり互換性無視。(Teency 1.0 は D6 L で点灯だが、D6 H で点灯)

  • 表の部品は少ないが、ATmega32u2 → USB → LED → タクトスイッチ の順でつけないと干渉するので付けるのが難しくなる。

  • 写真は、タクトスイッチを仮止めしたところまで。R3 は 後回しにして、裏に進んだ。

  • 今回はフラックスを使った。ATmega32u2 がベタベた。後でアルコールで拭く。

  • 半田吸い取り線を使ったが、ちょっとレジストがはげた。レジストが弱いんじゃないかという不安が出てきた。



  • 裏は、TAR5SB33 を先につける以外は順番での注意点はない。

  • 写真は、水晶の下を絶縁するために、マスキングテープを貼っているところ。水晶の脇に関係ない VIA が来ている。不安なので絶縁しておく。

  • 水晶を浮かしてつけようかと思って最初にハンダを盛ったが、やめた。



  • 最小限の部品を載せてひといきついたところ。抵抗とかけっこう適当。USB の R1/R2 は 1608 の 47Ωにしているし、D7 の LED (緑: Vf 2.0V) の抵抗 R4 も 1608 の 470Ω。

  • さらに、TAR5SB33 に付ける コンデンサを 0.1 uF にしてしまった。これは回路図が間違いで 0.01 uF が正しい。だからといって動かないわけではなく 電圧が上がるのに 10ms かかるようになる。
    間違いに気が付いたが、0.01uF を探すのが面倒だったので 0.1uF にしてみた。

あとひといき。




  • リセット回路周りは、D2 だけ付けることにした。(D3/C2/R5 は使わない)。あと D6 の LED (オレンジ: Vf 1.9V) の抵抗 R3 も 1608 の 470Ω にした。

  • これでひとまず 完成 -- のはず... が全然動かない。
    調べたら レギュレータ に 5V が来ていない。USB コネクタのハンダ付け不良だった。それだけ直したら OK 。

  • Atmel のブートローダが最初から入っていて、DFU atmega32u2 のドライバを要求される。
    これで、USB コネクタ, 水晶, atmega32u2 の電源周り の回路図 + ハンダ付けが確認できたことになる。

  • 次に FLIP 3.4.2 をインストールして、angel_loader_00d 添付の cdctest をビルドして書き込んでみる。

  • 接続すると USB162-CDC のドライバを要求される。リセットボタンを押すと ブートローダが再度使えるようになる。
    想定どおりの動作で、リセット回路もこれでいけそうだ。ちなみに、これでいけるなら D2 は 1K Ω でもかまわないことになる。

angel_loader_00d のテスト


cdctest は既に動いた。16MHz プリスケーラ 1/1 でも OK らしい。
次は、usbasp を動かしてみる。

    ... 全然動かない。これは思いあたることがある。

    TAR5SB32 の NOISE のコンデンサを 0.1uF にしたので、電圧が安定するまで時間がかかる。で、困るのはたぶん水晶。たぶん 周波数が安定するまで時間がかかるのだろう。

  • USB の初期化前に 20ms の delay を入れたら USBasp が認識された。

    実際に動かすには、ターゲットも用意しなければならないので、とりあえずパスして LED と RESET のテスト

  • 初期化で busy_led_on と connect_led_on をしてみたところ オレンジが USB 接続で消える。テストのため busy_led の on/off の論理を逆にして常時点灯にした。

    使った LED は、SEC2492 で 470 Ωだと 暗め。高輝度ではないしこんなものだろう。
    それはともかく、LED 点灯でリセットして HWB が L レベルになるかどうかを確認しないといけない。

    .. リセットボタンを押すと ちゃんとブートローダに切り替わった。リセット周りの回路はこれで確定しよう。

ここから先は、治具をつくってから。



治具は作ってみた。いろいろ方法を考えたのだが、USB ケーブルを差すので強度が必要。
低メスピンフレーム と L 型ピンヘッダでサンドイッチする方法を試すことにした。

L 型ピンヘッダは、少し押し出すことで、基板の上面と ピンが接触するようにしている。
どこか接触するだろうと考えてこういう風にしたが ダメかも。

    それだけだと接触不良が頻繁に起きた。L の内側の角にハンダを盛ることでようやく安定した。



もうひとつ AVR のボードを用意して お互いに書き込めるようにするのだ。用意したボードは USBasp が実際に動作するもの。2 枚作ろうかとも考えたが実績がないものを組み合わせてもしかたないのでやめた。

... 実績があったはずなのに動かない.. 記憶間違いか? で、USBasp を動かそうとしてはまった。
まだ動かせていない。.. やりたいことと違うのに。

もうひとつ作るか。.. と思ったがせっかくなので atmga32u2 側の USBasp のテストをしてみたところ
まったく問題なくシグネチャが読めた。ここまで動けば後は楽。

2号機製作


ブートローダとライタのテストをしていくわけだが、やっぱり 2 つあったほうがやりやすい。
... というわけで、結局 AT90USB162 の 2号機を製作することにした。

今度は写真がちゃんと取れたので写真で紹介。



まずは、AT90USB162 のまわりをマスキング。次に フラックスを塗ってAT90USB162 おく。
位置決めは慎重におこない、仮止め。



位置さえ決まれば、こんな風になっても、無問題。ハンダ吸い取り線できれいになる。ヤニで汚れるが後でアルコールで拭けばきれいになる。



次は、USB コネクタ。マスキングをして、仮止めする。



こんな風になっても気にしない。そんなことよりランドにしっかりハンダを載せるほうが重要。



LED → タクトスイッチ → R3 の順で付けて、表面完成。



続いて裏面。下に ティッシュを丸めたのをおいて マスキング。そして完成。



記念写真。今回は、部品をできるだけきれいにつけるようにがんばった。.. でもこの程度。
そして 今回も 一発では動かなかった。失敗したのは、水晶のハンダ付け不良。

作った感想

  • 失敗しやすいのは、水晶 と USB コネクタのようだ。水晶は、裏にパッドがあるので難しいわけなので、先に水晶の裏 GND でない信号線 2 ヶ所にハンダを盛ったほうがよいかもしれない。USB コネクタは ケースが 端子にかぶっているので やりにくい。これは、ちゃんとハンダを載せれば 問題ない。

  • 抵抗は 1608 を 使ったが 2012 と比べて難しいわけではなかった。2012 用のランドなので、ランドが広くむしろ 2012 より楽かも。

  • D3/C2/R5 を使わないようにしたが、少々難がある。すなおにつけたほうが良い。


ケーブルを作ってこんな風に配線。黄色のマークが今回作った 2号機。

ケーブルは、LEDの足で コンスルー風味のものを作ってみた。わりとしっかり刺さっているが、なんども抜き差しするとゆるくなってくる。ダメになったら、0.4mm の 洋白丸線でおなじ形状のものを作ってみるつもり。

追記: 足をつける。



いろいろテストしたりしだすと、やっぱりブレッドボードが使いたくなってくる。結局足をつけることにした。



普通に ピンヘッダとかを使うと背が高くなる。それを嫌ってこんな風にした。
ダイオードの線は結構硬いので、足に使う。端を 3mm ほど折り曲げて基板にしっかり刺さるようにしてハンダ付け。(実際は、ブレッドボードに基板をおいて上から挿した)
ダイオード 1本で 4 本取れる。ダイオードは使えなくなるが有効活用できたのでヨシとしよう。



上から撮った写真。下の 3 つのうち RESET は他に線が出ていないので、LED の足を加工してつけている。
左に見えるジャンパも LEDの足で TX/RX のループバック用。




ケーブルも自作。しっかり挿せるように工夫してみた。
... といってもたいしたことはなく、LED の足を 半分に折り 割りピンのような形状にする。
で、割りピンの頭の方をハンダ付け。

ブレットボードの接点は、上下にある。縦方向は薄くして、横方向を太くすれば安定するのだ。そして、LED の足は角線だからそういう形状にするのに都合がよい。
ちなみに、頭の方をハンダ付けするのは、そうしないと入らないから。きちんとつぶせば 逆でも良いのだが、なかなか難しい。

    秋月から出た 細いピンヘッダ は 0.5mm 角 長さ 9mm のようだ。これを 2 本束ねると良いかも。ケーブルにハンダ付けするときは、ブレットボードに挿した状態でやると良さそう。
posted by すz at 11:10| Comment(72) | TrackBack(0) | USB162

2010年11月24日

Teensy(1.0)互換ボード

PS3 のおかげで、AT90USB162 のボードが 売れたそうだが、ボードの1つとして、Teensy USB Development Board というのが出回っている。

たとえば、次のようなものがある。

調べてみると、これらは『PJRC』が開発した、Teensy 1.0 の コピー品らしい。中身は まったく同じではなく、LED が 2 個付いているのが特徴。

PJRC』は、回路図 や ピン配置図 それに 各種ツールや 独自のブートローダのバイナリまで公開している。

互換品を作ることは簡単だと思えるのだが、上記のものは パッケージや基板のパターンまで コピーしているので、あえて コピー品 と書いた。Teensy のような超コンパクトな開発ボードは今なお魅力的で、本当は薦めようと思って調べたのだが、どうにも薦めがたいことが分かった。そして、開発元では もう 生産していないように見える。欲しくとも正規品は手に入らないようだ。

    現在は、Teensy 2.0 になっていて、ATMEGA32U4 になっている。ATMEGA32U4 は 機能が多く魅力的なチップなのだが、チップの入手性が非常に悪く(いまは)電子工作で使いにくい。AT90USB162 や 互換のATMEGA16U2, メモリ増強版の ATMEGA32U2 は 価格も安く いまなお魅力的な チップだと思う。

前置きが長くなってしまったが、そういうわけで、Teensy 1.0 互換ボードを作ってみようと思う。

    本当の理由は、Fusion PCB で基板を 作りたかっただけなのだが、ネタ的にも面白そうだ。
    あと、Teensy 独自のブートローダ はソースが公開されていないし、勝手に載せて売ったりするのはまずそうなので、USBaspLoader 互換の ブートローダを 提供しようと思う。
    (注意) 私自身は売るつもりはないが、販売で添付可能なものを提供しようという意味。ライセンス料を取るという意味でもない。安くとも薦められないものは困るのでどうにかしたいだけ。

基板の設計


公開されている Teensy の 回路図ピン配置図を元に eagle で基板を設計することにした。部品は、基本的に秋月で手に入るものをベースに選定する。

  • 部品については、今回新たに選ぶわけでなく、昔作ったボードの部品ライブラリを使う。

  • Teensy は 5V 専用のように見える。ここは 気に入らないので、レギュレータを付けて 3.3V で動かす。

  • 大きな部品を使い、さらに部品を増やすわけだから、表面だけでは入りきらない。当然裏面も使う。

  • リセット周り -- どうなっているのかと思ってたのだが、ダイオードを使って 1 個のボタンで済ませている。リセット後 しばらく HWB が L である必要があるわけなのだが、RC で delay させることで対処している。HWB の機能は、リセットが H レベルになった瞬間に HWB の値を取り込むから、RC の時定数はあまり関係ない。

    そんなことより、プルアップがない。常に L レベルのような .. ? 実用として使う場合は、自分でプルアップせよということ?

      HWB がどういうものか説明しておく。これは、リセット時に HWB = L だと ブートローダを起動する仕組み。ヒューズビットの設定で、無効にすることもできるし、常にブートローダを起動するようにもできる。
      HWB は 単なる入力で、プルアップ や プルダウン するオプションはない。




    angel162 ボード(サイズ: 31.75 x 19.05)

  • angel162-01.zip (全部入り)
  • angel162-01-out.zip (提出したファイル)

      (改修版)
    • angel162-02.zip (全部入り)
    • angel162-02-out.zip (Fusion PCB 提出用ファイル)
      (改修版2)
    • angel162-03.zip (全部入り)
    • angel162-03-fusion.zip (Fusion PCB 提出用ファイル)
      (スルーホールまで レジストしないよう修正)

    • 同サイズの違うボードも設計した →『AE-UM232Rピン互換ボード』の記事参照



      UVCC を USB から入力し、UCAP を VCC と切り離した。こうすると、VCC に 5V 入力が可能になる。
      実際に 5V 入力にするには、TAR5B33 を付けずに IN と OUT をジャンパする。LED や HWB まわりはあえて変更していない。

      あと 外形線を 0.2mm にして、0.1mm づつ外側に広げた。

  • できあがったのは、こういうもの。出来は悪いかも知れないしバグがあるかも知れないが、もう Fusion PCB に発注してしまった。

      angel162-01-out.zip を送れば良いだけなので、eagle を使えない人でもこのボードを作ることができる。ちゃんとライセンスを書いてないが、GPL に準じようと思う。要するに angel162-01.zip の生成物であるボードを売ったり配ったりするなら それを作った eagle ファイルの (ボードを受け取る人への)提示が必要。改変も OK 。

  • 問題は名前。ファイル名にも使うし、なにか付けなければならない。Teensy は 商品名なので使えない。ベタなんだが、Teensy -- 天使 -- Angel という連想で、angel162 にした。

  • バグ情報:(ほんとうに作ろうと思っている人は注意!)

    (1) D6 の LED の極性が間違っていた。H で点灯するようにしたが、L で点灯だった。

    (2) UVCC を 3.3V に接続してしまった。これでも問題は起きない。が、推奨は USB VBUS に接続する(or 無接続)。

    (3) D7 (HWB) のプルアップはしていない。(Teensy 1.0 も) これで大丈夫なのだろうか?
    さらに、LED まで付けてしまっている。

      基板のパターンをよくみると .. LEDの K を GND から 切り離して 近くの 3V3 につなげる改修はできそうだ。
      極性が逆になるから、LED も逆に付けることになる。

      さて、HWB だが、他のバージョンの Teensy は、プルダウンしているだけだった。
      よくよく考えるとそれで良いのだった。

      通常外部リセットのときしか ブートローダは起動しない。
      ブートローダは、外部リセットかどうか知ることができる。自分でチェックして、外部リセット以外は アプリケーションを起動させてしまう。

      ボタンは1つしかないから、それが押されたときは常に外部リセットだ。だから HWB は 弱いプルダウンだけで十分なのだ。もし、実用回路で コントロールしたければ、強いプルアップを付ければよい。

      で、常にプルダウンするなら L で点灯することはできない。だから改修もできない。

      では、D2/D3 とかはどうしよう。... D7 に LED をつけるなら他にいらないような気がするので、まず C3/R5/D3 はつけるのをやめる。もし必要なら C3 に 100K とかをつけて R5 はジャンパ 、D3 はオープン。
      D2 には、ダイオードではなくて 1K をつける。これぐらいで良いのではないだろうか。

        追記: LED には起電力がある。指で 押さえてリセットすれば ブートローダに入れる 。
        それが嫌ならプルダウンでよいと思うのだが、100K で良いのかどうか?

      もし互換性が重要なら D7 の LED はあきらめて 1608 型の LED にして D6 側だけ付けて 改修する。Teensy 1.0 と おなじ回路にもできるし、ダイオード(D2/D3)を使わない簡易回路にもできる。

      どちらにせよ 外部リセット のチェックは必要だ。ブートローダの config を変更することにする。

    なんだかイマイチのようだが、まだ大丈夫。

    ピン配置図:


    こんな感じで、サイズは 秋月 AE-UM232Rと同一。(実はフチがあるので、ちょっと大きい。オリジナル Teensy はたぶん同一)

パーツリスト


パーツリストは、ここにまとめておこう。
(注意回路を見直し中:付けるパーツを変更予定)


  • 表面実装のコンデンサ については、1uF は秋月で 安く手に入る 1608。あとは 2012 をベースにした。ただ 22pF は 秋月では手に入らない。 3216 10pF が手に入るのみなので、一応使えるように配慮した。(Teensy 1.0 も 10pF だし)10pF で発振すると思うのだが、無理なら 2 枚重ねで対応してほしい。

  • 抵抗は、秋月では無理。1608 なら リールが買えるが ... 2012 のパターンでも 1608 も使えるはずなので、すすめはしないがリール買いする手はある。おすすめなのは、共立のチップ抵抗セット。千石やマルツでバラ買いする手もあるし、ATMEGA32U2 をデジキーで買うならついでに買っておく手もある。

      MCR10で検索して、デジキー型番のルールが分かったら、型番直打ちで発注書に登録すると効率がよい。
      そういえば、水晶用の コンデンサ も 合わせて買っておくとよいかも。これとか。

  • 2色チップLED が入手できなかったり、 赤・黄の組み合わせが気に入らなければ、1608 タイプを 2 つ付ける手がある。

  • ATMEGA32U2 は、デジキーで 単価 392円で入手できる。国内だと マイクロファンで 単価 630円 -- 数を買わないなら こちらの方が良いかも。AT90USB162/ATMEGA16U2 の入手は実は難しい。

    U1 AT90USB162/ATMEGA16U2(/ATMEGA32U2) TQFP-32 ( 0.8mm ピッチ)
    U2 秋月 TAR5SB33 3.3V レギュレータ
    D1 秋月 SEC2764C 2色チップLED
    D2,D3 秋月 1SS352
    X1 16MHz 秋月 FA238

    R1,R2 22 SMD 2012
    R3,R5 1K SMD 2012
    R4 330 SMD 2012

    C1 10u SMD 2012 (秋月 10u)
    C2,C3,C6 1u SMD 1608 (秋月 1u)
    C4,C5 22p SMD 2012 (マルツ、千石とか)
    (または 10p /10p x2 (秋月 3216 10p)
    C7 0.1u SMD 2012 (秋月 0.1u 100個,0.1u 20個)
    0.01u SMD 2012 (秋月 0.01u)
    0.01u SMD 1608 (秋月 0.01u 100個 100円
    - 0.1u では電圧が上がるのに 10ms かかる。FUSEBIT SUT を 11: (65 ms) にする。
    - 標準の 0.01u では 1ms なので SUT を 10: (4.1ms) にする。
    (0.01u は在庫が少ないようなので、0.1u で良いことにした) 0.01u が復活!
    - default の SUT 01: (BOD 許可) の場合 usbInit() 前に 20ms
          遅延を入れる。
    SW1 秋月 TSKB-2JL,LS6J2M-T
    CN3 秋月 UX60A-MB-5ST USB miniB

    メモ: 10 個分の部品代 (送料含まず)

      ボード 2020円 ( $23.52 x 85.6 )
      1100円 ($13.42 x 82.3) 2011.06.06
      ATMEGA32U2 3960円 2011.06.06 (25個なら 6221 円)
      TAR5SB33 280円
      SEC2764C 200円 (20個 -- 10個あまる)
      1SS352 200円 (40個 -- 20個あまる)
      FA238 600円 (12個 -- 2個あまる)
      TSKB-2JL(LS6J2M-T) 200円
      UX60A-MB-5ST 800円 (12個 -- 2個あまる)
      10uF 100円 (20個 -- 10個あまる)
      1uF 200円 (100個 -- 70個あまる)
      0.01uF 100円 (100個 -- 90個あまる)
      10p 200円 (20p にすると仮定 -- 40個)
      抵抗 500円 (10個 100円とみなす)
      ----
      合計 8240円

    10個もいらないと思うが、これぐらいの部品代になる。ひとりで揃えるには高いか ..
    送料は、ついでに買うのでなければ 2000円+800円。

    実際作ったのだが、C3/R5/D3 は不要だと分かったので付けていない。
    ... ただし、そうした場合は、ブートローダを起動するときに、LED に光が入らないように指で押さえて リセットボタンを押す必要がある。

ブートローダ


AT90USB162 で使える USBaspLoader は 昔作った。『usb162用USBaspLoader』の記事に載せているのだが、いろいろ詰め込んだせいで 余計なものが多い上に説明が少ない。

新たに angle162 用に まとめなおして、説明を付けようと思う。

    AT90USB162 , ATMEGA32U2 などは、最初から Atmel のブートローダが書きこまれている。flip や dfu-programmer を使ってプログラムを書きこむことができるので、どうしても必要なものではない。

    これは、『avrdude(avrdude-GUI) のインターフェイスで操作したい』とか、『Arduino IDE(+Teensyduino)を自作ボードで使いたい』といった場合に使う。

    注意!) AT90USB162 の Atmel の ブートローダはここからダウンロードできるので 元にもどすことも可能なのだが、ATMEGA32U2 はない。いったん消してしまうと 元には戻せないので注意。

      (読めるらしいので、バックアップしたほうが良い)
      ライタでは読めないがプログラムからは読める設定。ブートローダを改造して アプリケーションとして実行すれば読むプログラムは用意可能。ブートローダを試す障害になるのは困るので、添付する方向で検討してみよう。

    LUFA にいろいろな種類の ブートローダがインプリメントされているので、それを使うのも手。DFU ブートローダもあるらしい。

USBaspLoader 互換ブートローダ:

  • angel_loader-1.4c.zip (暫定版)
  • angel_loader-1.4.zip (最新版)
  • angel_loader-1.3.zip (旧版)
  • angel_loader-1.2.zip (旧版)
  • angel_loader-1.1.zip (旧版)
  • angel_loader-1.0.zip (旧版)
  • angel_loader_00g.zip (旧版)
  • angel_loader_00d.zip (旧版)

  • avrdude-serjtag04k.zip (おまけ: 1.4 に対応)

  • ver 1.4c (1) angel_loader のバイナリサイズを減らし 32u4 も 2KB 以内にした
    (2) serjtag 更新中 (たぶん動かない)
  • ver 1.4 (1) serial と serjtag を見直しくっつけられるようにした。
     DTR=0 で serjtag / DTR=1 で serial -- だいぶ変更したので リビジョンを上げた。
     avrdude-serjtag も対応版にした。(実は windows 版は無修正で問題ない)
    (2) UM162ボードでは ボーレートを 1200 にして RTS=0 にすると リセットをかけ ブートローダが起動するようにした。
  • ver 1.3 (1) UM162ボードに対応 -- 『AE-UM232Rピン互換ボード』の記事参照

      このボードだけ serial の DTR 出力に対応。(未テストで極性が逆かも) 。あと、このボードだけ usbisp2 の ISP で 1MHz クロック出力を付けている。(これも未テスト)

    (2) binary デレクトリの整理と README 更新
  • ver 1.2c (1) binary デレクトリの整理と README 更新
    (2) ブートローダに lockbit 書き込み機能を追加
    (3) 32u4 版がかなりまともになった。
    (4) 32u4 での serjtag (ADC 機能) 確認。バイナリ添付開始。
  • ver 1.2a (1) binary デレクトリの整理と README 更新
    (2) オリジナルブートローダバックアップ用プログラム添付
    (3) 32u4 版添付 (少しまともになった。対応ボードは dac23-u4)
  • ver 1.2 ついに 1.2 にした。
    (1) mega32u4 対応(途中)
    (2) PDI/TPI 対応は完了していないが、大分形になってきた。
  • ver 1.1h (1) usbasp2: PDI/TPI 拡張中のコードはまだ動かない。(修正中)
    (2) ISP のチャネル変更版(ISP2)が動いたので整理してまとめた。
  • ver 1.1f (1) usbasp2: PDI/TPI 拡張中のコードを入れた
  • ver 1.1c (1) レギュレータを off しないようにした。
    (2) cdc162 の API 拡張
    (3) USBasp プロトコル拡張版のフレームワークを入れた。
  • ver 1.1a (1) cdc162 API 拡張 (serial/cdctest で 対応中)
    .. 1.1a などは 暫定版。区切りが付いたら 1.2 に上げる。
  • ver 1.1 (1)USB-シリアル ファームウェア添付。
          (2)バイナリの elf ファイルを添付するようにした。
  • ver 1.0 ブートローダと ライタの動作確認。

まず最初に、Teensyduino でどう対応するのかについて書いておく。これが出来れば、Teensy Loader にこだわる必要はなくなるわけで重要なのだ。

    USB直結Arduino互換ボード』を みて欲しい。METALABMETABOARD が元ネタなわけだが、こちらの方がわかりやすい。

    さて、なにをしているかというと、board.txt を書き換えて、書き込みソフトを変更しているわけだ。ブートローダのインターフェイスは 同じ USBaspLoader だから まったく同じ手順で 使えるようになるはず。

続いて解説。

そもそも、どういうものかというと ... USBaspLoaderを元にして、自作してきた USB162 ライブラリ とリンクできるよう修正をしたもの。diff が取れないぐらい変更してしまったが オリジナルとロジックは(基本)変わらない。

    変えたのは、singature ぐらい。チップから取得することで、同じバイナリが使えるようにした。

標準の設定は、今回作った angel162 に合わせているが、他のボードにも対応できる。設定しなければならないものは次の 4 つ。

  • 黄(or 緑) LED(D7)

    Teensy 1.0 には、この LED は付いていない。コピー品は 2 つ付いているし、経験上 2 つの方が便利なので、D7 に付けることにした。

    割り当てた機能は、『BOOTLOADER 実行中 』を示すステータス。

    bootloaderconfig.h に connect_led_on()/connect_led_off() が定義されているので編集することで 他の ボードにも対応できる。
    bootLoaderEnter()/bootLoaderExit() で初期化/終了処理をしているので、こちらも合わせて変更する必要がある。

  • 赤 (or オレンジ)LED (D6)

    割り当てた機能は、『BOOTLOADER コマンド実行中 』を示すステータス。
    上と何が違うかというと、BOOTLOADER が コマンド待ちのとき、黄色は付いたままだが、赤は消える点。書き込み中 ピカピカ光る。

    bootloaderconfig.h に busy_led_on()/busy_led_off() が定義されているので編集することで 他の ボードにも対応できる。
    bootLoaderEnter()/bootLoaderExit() で初期化/終了処理をしているので、こちらも合わせて変更する必要がある。

  • HWB の回路

    HWBは、D7 と決まっているわけだが、回路は 1種類ではない。昔作ったボードはスライドスイッチで、切り替えると ブートローダを終了してプログラムを起動するようにしていた。

    また、ヒューズビットで 常に ブートローダを起動するようにもできる。この場合は、ブートローダ側で プログラムを起動するかどうかを判断する。

    動作を変更する define を 3 つ作った。以下推奨する設定の例

    CHK_EXTRF USE_HWB CHK_HWB_LEVEL
    1 1 0 外部リセット なら ブートローダ起動
                      (HWBE = 0 が前提の動作 )
    1 0 0 外部リセット かつ HWB が L なら ブートローダ起動
    (HWBE = 1 / BOOTRST = 0 が前提の動作)
    1 0 1 外部リセット かつ HWB が L なら ブートローダを起動
    するが、HWB が H になったとき アプリプログラム起動
                      (スライドスイッチ用)
    補足 1) ブートローダを起動しない = アプリプログラム起動
    補足 2) USBaspLoader には DISCONNECT命令で終了しアプリプログラムを起動する
         機能もある。(デフォルト: -- 抑止も可能)


  • MCUの種類とクロック

    クロックは、Makefile 上の F_CPU で指定する。1600000UL(16MHz) or 8000000UL(8MHz) が指定可能。
    それに加えて 水晶 16Mhz のとき、プリスケーラで 8MHz にする指定もできる。
    ( 3.3V で 保証されている 8Mhz にしたいとき 使用する。)

      このようにするには、F_CPU は、8000000UL(8MHz) に指定して、F_SCALER を 1 にする。

      ちなみに、F_SCALER が 0 の場合は、1/1 に設定するので、ヒューズビット(CKDIV8) を 1/8 にしても問題ない。逆に 8MHz にする場合、一瞬 16MHz になるのを避けるために 1/8 にする。

      また、F_SCALER を define しないと、プリスケーラの 設定を変更しない。これはほんのわずかでもコードを減らしたいときに使う。

    MCU は、at90usb162 と atmega16u2 , atmega32u2 に対応しているが、at90usb162 の指定で十分(なようにしている)。むしろ BOOTLOADER_ADDRESS の方が重要だ。

      asis の WinAVR-20100110 では、問題があったかと思う。asis では、at90usb162 の指定でビルドすること。

      MCU の指定を変更しても 同じオブジェクト・ファイルが生成されるのは確認した。( ライブラリのバイナリが違うので elf ファイルは同一にならない。) ちなみに、atmega8u2 はページサイズが違うので、同一にならない。

    現状のコードサイズは 2KB 以下(1984 バイト)で、2KB 以下を守ろうと考えている。

     BOOTLOADER_ADDRESS=3800 -- AT90USB162/ATMEGA16U2
     BOOTLOADER_ADDRESS=7800 -- ATMEGA32U2
    デフォルトのヒューズビットは 4K 用になっている。その場合は、

     BOOTLOADER_ADDRESS=3000 -- AT90USB162/ATMEGA16U2
     BOOTLOADER_ADDRESS=7000 -- ATMEGA32U2
    なお、ヒューズビット(BOOTSZ=01)も合わせて設定変更する必要があるので注意。

    なお、atmega32u4 には対応していないが、PLL 周りを修正することで対応できそう。ものを持っていないので 自分で修正するつもりは まだない。

      入手したので、対応することにした。一応は動いているが、動作がいまひとつおかしい。
      特に USBの接続がよく失敗する。(修正済み)

      ちなみに、BOOTLOADER_ADDRESS=0 とした上で 、LDFLAGS の --section-start=... となっている所をコメントにすると アプリケーションとして実行できる。

      注意点を書いておくが、このブートローダで ブートローダを更新しようとすると 途中まで書いて壊れる。壊したくなければ ロックビットで保護すること。


    MCU と BOOTLOADER_ADDRESS を変更することで、ATmega8u2 にも対応はできる。が、わざわざ 容量の少ない ATmega8u2 を電子工作で使う意味はないと思う。Arduino UNO に応用する意味もあまりないだろう。
    .. ということで無視する。

      arduino UNO の ATmega8u2 は 最低限度の配線しかしていない。回路図(pdf)をみると
      PB1 (SLCK) ISP コネクタ
        PB2 (MOSI) ISP コネクタ
        PB3 (MISO) ISP コネクタ
      PD2 (RXD) arduino TXD
      PD3 (TXD) arduino RXD
      PD4 RX LED (L active)
      PD5 (XCK) TX LED (L active)
      PD7 (HWB) arduino DTR
      これだけ。たとえば ライタにするにしても 線が足りない。せめて PB0(SS) を 外に出しておいてくれれば... 改造するとすれば LED から線を引き出すぐらいか。でも、誰でもできる感じではなさそう。
      ただ、この割り当てが 今後リファレンスとして使われるかも知れない。覚えておこう。

  • バイナリの種類
    binary ディレクトリに 以下の 4 つを置くことにする。

     angel162_loader_16M.hex AT90USB162/ATMEGA16U2 水晶 16MHz / 8MHz 動作
     angel162_loader_8M.hex AT90USB162/ATMEGA16U2 水晶 8MHz / 8MHz 動作
     angel32u2_loader_16M.hex ATMEGA32U2 水晶 16MHz / 8MHz 動作
     angel32u2_loader_8M.hex ATMEGA32U2 水晶 8MHz / 8MHz 動作

    水晶 16MHz / 16MHz 動作 のバイナリは作らないことにした。なお、8MHz はテストできないが F_SCALER が違うだけなので大丈夫なはず。

    LED は、D6/D7 を H/L レベルで駆動している。だから LED の 極性が逆のボードでも このバイナリを一応使える。(表示が逆になるだけ) 。ただし、D7 を H/L にできないような ボードでは このバイナリは使えず、(bootloaderconfig.h を適切に変更しての) リビルドが必要になる。

ヒューズビット


非常に重要なのだが、いつも忘れているのでおさらい。

# Fuse extended byte:
# 0xf5 = 1 1 1 1 0 1 0 1
# | \-+-/
# | +-------BODLEVEL 0..2 (101 = 3.0 V)
# +-----------HWBE (0 = HWB enable )
# Fuse high byte:
# 0xd3 = 1 1 0 1 0 0 1 1 -- BOOTRST (reset vector == 0 but using HWB)
# ^ ^ ^ ^ ^ \+/
# | | | | | +------- BOOTSZ (01 = 2k bytes/ 00 = 4k bytes)
# | | | | + --------- EESAVE (preserve EEPROM over chip erase)
# | | | +-------------- WDTON (if 0: watchdog always on)
# | | +---------------- SPIEN (allow serial programming)
# | +------------------ DWEN (debug wire enable)
# +-------------------- RSTDISBL (reset pin is enabled)
# Fuse low byte:
# 0x5e = 0 1 0 1 1 1 1 0
# ^ ^ \ / \--+--/
# | | | +------- CKSEL 3..0 (1110: crystal - normal)
# | | +--------------- SUT 1..0 (01: fast + BOT)
# | | (10: boottime 4.1ms / 11: 65 ms)
# | +------------------ CKOUT (if 0: Clock output enabled)
# +-------------------- CKDIV8 (if 0: divide by 8)

これがおすすめ?
注意点)

  • 8MHz で動かす場合、CKDIV8 を 0 にする。
  • SUT 11: boottime 65ms が無難ではあるが、デフォルトは違う
  • BOOT_ADDRESS を 3800/7800 に変更したら BOOTSZ 01 を忘れずに


補足:
ATmega32u2 の デフォルトは、efuse 0xf4 / hfuse 0xd9 / lfuse 0x5e 。(AT90USB162 も同じ )

BOOTSZ 以外の変更をしないで動くようにプログラムで対応するには、usbInit() の前に 20ms の遅延を入れる。

おまけ : ライタプログラム (USBasp)


ブートローダをどうやって書きこむかという問題がある。

AE-UM232Rを使ったライタなどなんでも良いからライタを用意できれば良いわけだが、別の方法もある。

このボードは、汎用ボードなわけで、ライタになるプログラムを入れればよい。2 つ作れば問題ないようにはできるわけだ。

このチップは、標準で Atmel の ブートローダが入っている。それで、ライタになるプログラムを書きこめば、2 つめのブートローダを 書きこむことができる。安定して動くことが確認できれば、1 つめも書き換えれば良い。

ライタになるプログラムを、USBasp (not USBaspLoader) 互換 にしておけば、 PC のライタソフトは 1 つで良く便利。

binary ディレクトリに以下のものを置いておく。(例によって未確認.. というよりまだデバッグ前)

 asp162_16M.hex 共通 水晶 16MHz / 8MHz 動作
 asp162_8M.hex 共通 水晶 8MHz / 8MHz 動作
ソースコードも添付(usbasp ディレクトリ)
配線:


    ターゲット側 ライタ側
    MOSI ---- MOSI
    MISO ---- MISO
    SCLK ---- SCLK
    RST  ---- SS

    VCC(3V3) --- VCC(3V3)
    GND ---- GND

    USBasp は、SPI インターフェイスを使っているので、ピンの変更はできない。
    ちなみに ターゲット側 MOSI - マスター側 MOSI となる。Master Out Slave In だから そのとおりの意味になっている。

おまけ : ライタプログラム2 (serjtag)


USB910 というのをこのブログ開始時作っていて serjtag という独自プロトコルの の JTAG 用 インターフェイスまで作って拡張していたのだが、放置していた。ATMEGA32U4 が手に入るようになったら 移植しようと思っていたのだが、いつまでたっても手に入らないので忘れていた。

この機会に移植しようと思う。自分で全部作っているわけで移植自体は簡単にできるようにしている。とりあえず 0.1 版では ビルドだけできるようにして 添付。

機能は、AVR910 互換ライタ + serjtag + i2c マスタ。serjtag は SPI インターフェイスでもあるので ライタにもつかえるし、SDカードを制御するテストなどにも応用できる。I2C マスタも デバイスを制御するテスト用。だいぶ古いから デバッグしながら 直していこうと思う。

ちなみに、serjtag で SPI インターフェイスを使えば bitclock を 8MHz まで上げられる。が、CDC-ACM を使うので実効スループットは あまり上がらないだろう。このあたりは、チューニングしてみたい。

    正直なところ、FT2232HはもとよりFT2232にも性能ではかなわないだろう。... だがいろいろいじれるのが利点。ツールとして欲しい機能は他にもあるので付け加えていこうと思う。


追記: 謎なボードが出てきた。

  • Designer's Minimus AVR USB Modchip Jail Break Dongle for PS3』 -- $18.60 dealextreme



    これは何? Designer's となっているからには、パチモンなわけだが... ちゃんと本物があるらしい。
    http://www.minimususb.com/ MCU は、AT90USB162 だそうだ。


    普通に Atmel のブートローダ使っていてソフトの著作権は問題ないし、変なデザインだが開発ボードだし。デザインはマネているかも知れないが、微妙に違うかも知れないし。-- まぁ許容範囲内か。

    よくみると LED は 3 つある。あと内蔵レギュレータ使っていて 5V と 3.3V の切り替えができる。良いのではないだろうか?

    それはともかく、本物は国内でも売られてたのか。これを含め AT90USB162 だけでいくつ出たのだろうか? Arduino は全部で数万台らしいが .. それを軽く超えるような気がする。

追記: 2010/12/3 基板がきた。



    製作は別記事『Teensy(1.0)互換ボード 製作編』。



    こんな風に ATmega32u2 版と AT90USB162 版を 製作した。次のステップは、USBasp 互換ライタと ブートローダのデバッグ。

    現時点で USBasp 互換ライタのほうは動いていて、それで 書き込んでブートローダのテストをしている。


追記: 所感

秋月の AE-UM232R と同じサイズで (ソフト次第で)同じようなことができるボードになった。AE-UM232R も 良いのだが、足が最初から付いているのだけは気に入らなかったりする。

いくつか作れるだけのパーツはあるし、AE-UM232R を使うかわりに これを使っていこうと思う。

ただ、USB-シリアル コンバータは、まだ作っていない。これがないと 片手落ち。
... そういえば ゆきさんの R8Cプログラマ は USB-シリアル コンバータの機能を含んでいる。これ ベースに機能を削って でっちあげようかな。

    ただ、プログラムに 日本語は入れないことにしているから ... どうしよう。参考にさせてもらって作り直すか もしくはコメント削りまくるだけにするか。

    追記: 結局、ベースにさせてもらって、自分の趣味で変更。一応 ループバックで動作したので v1.1 に添付することにした。

デバッグの記録


デバッグの記録 0d 版〜

    USBasp : 最後のページの書き込みのところにバグがあったが、その他はだいたい OK のようだ。

    実をいうと、割り込みベクタを登録していないのに、UDIEN の EORSTE にビットを立てている。そして、そうしないと 動かない。

    自分で書いたコードだが忘れている。... 調べたら USB reset が起きたら _bad_interrupt に ジャンプして 最初から動くようになっていた。

    アプリケーションはそんなコードで問題ない。だが、ブートローダでは 割り込み原因を調べているので、不具合がおきる。さて。

    -- リセットでない場合 はブートローダを再実行しなくてはならない。それを判断するのは可能なようだ。

デバッグの記録 00g

    USBasp のほうは FIX しようと思う。問題はブートローダ。

    ブートローダは動くのである。ただし 最初の 1回だけ。ブートローダで USBasp を書き込むとリセットを押しても USBasp が起動してしまう。(ブートローダを 壊してしまっているのではないことは確認済み )

    ううむ困った。

      Atmel のブートローダは動いているわけだから、ブートローダで アプリケーションに制御を渡していると考えられる。本当のリセットはたぶん問題ないが、USB からのリセットの結果の割り込みで main が再実行されたときに アプリケーションに制御を渡してしまうに違いない。

      だとすると リセットボタンを押しながら USB に接続すれば 1回目と同じ状況のはずだからブートローダが起動するはず

      .. と考えてやってみたら正解だった。 期待どおりに ブートローダが起動した。

      確実にブートローダに入れるならこれを仕様にしてしまっても良いのだが、気持ち悪いのでできたら直したい。

      ... おかしい? うまくいかない。さらに、常に ブートローダに入るようにしても起動しない。
      よくよく考えてみれば、LED には起電力があったのだった。明るい場所で リセットを押しても HWB が H レベルになって ブートローダに来ない。LED を指で押さえて リセットを押せば OK だった。

      ちゃんと動くようになったので、ver 1.0 にする。

    デバッグの記録 ver 1.0

      ゆきさんの R8Cプログラマ から USB-シリアル コンバータの機能だけにするよう コードを削り、serial/ を作成。
      機能は、8N1 専用 でボーレートだけ変更できる。115200/57600 bps はサポートしているが、最大はよくわからない。(値によって誤差が大きくなる -- 115200 の倍数は無理)

      バイナリは、serial162_16M.hex (動作は8M) / serial162_8M.hex 。

      TX-RX を接続してのループパックしか試していないので、バグがあるかも。あと、LED の付き方が気に入らないので修正予定。

      あと バイナリファイル(HEX)の元の elf ファイルも添付するようにした。ディスアセンブルが avr-objdump -d で出来るし、コンパイルしないで バイナリを変更して LED のポートを 変えるとかを 一応考慮。ブートローダはサイズが厳しいので。

    デバッグの記録 ver 1.1

      LED は、50ms 残光 する特性をつけた。瞬間でないので 通信しているのがよく分かる。
      あいかわらず ループパックしか試していないので、ボーレートに誤差があっても分からない。

      callback_set_baud(long) という API があるのだが、これだと ボーレートしかわからない。CDC162_EXCONT で切り分けて 1 の場合、API を変更し、databit/parity/stopbit も扱えるようにした。

      さらに、SET_CONTROL_LINE_STATE とか SEND_BREAK に対応する API も追加。

        SET_CONTROL_LINE_STATE では、1 バイトの データが VALUE にセットされて 来る。フォーマットは、

        bit0: DTR
        bit1: RTS

        BREAK は 2バイトのデータで VALUE にセットされて来る。意味は BREAK 時間 (ms) だが、Linux だと (-1) か 0 しか 渡していない。

        これをアプリケーションプログラムで制御するのは (OS に API があるので)簡単で、サポートしておくと これで モードを変えたりできる。SEND_BREAK も 同様に OS に API がある。

      • Windows は、EscapeCommFunction() をつかうが 必要に応じて SetCommState() で、DTR_CONTROL_DISABLE/RTS_CONTROL_DISABLE しておかなければらない。

      • Linux とかだと ioctl() の TIOCMSET をつかうが、やはり termios インターフェイスをつかって RTSCTS を無効にしたりしないといけない。

      詳しくは、ソースコード( cdc162.h と cdc_main.c )を参照。

    API だけは入れておくが中身は LED を点灯させて チェックするコード。

      チェックしてみると、初期化で OS が DTR/RTS を 設定する。BREAK は勝手に送信されないので、動作モードに使う場合 BREAK がきたときに有効にしたら良いと思う。

        cdctest にチェックするコードを入れてみたが、BREAK 送信で 2 回来るような ... ?
        それはともかく、デフォルトは DTR 1 RTS 1 。で、BREAK が来て mode が変わっていたら 内部動作を変える ... みたいなのでどうだろう?

      ... そういえば シリアルベースの (ダム)ライタというのも考えられる。通常の AVR は SPI モードを使えばよいし、たしか XMEGA や Tiny10 とかも XCK 出力 するようにして RX + TX を接続 して 信号線にすれば 良かったはず。もちろんソフトはいるわけだが、クロックを常時出力しないといけない XMEGA では (ダム)ライタは厳しかった。いずれ考えてみよう。

    ちなみに、ステータス は、RX/TX ではない 第三の インタラプト・エンドポイント にデータを送るようだ。パケットのヘッダは 8 バイトで、後ろに 2バイトのデータが付く。

      uint8_t RequestType
    uint8_t NotificationType
    uint16_t Value
    uint16_t Index
    uint16_t Length

    ヘッダは、コントロールのパケットと同じ形式。Linux だと対応しているパケットは、
     
    NotificationType: 0x20 (NOTIFY_SERIAL_STATE)
    RequestType: 0xa1 ( DIR_IN | TYPE_CLASS | RECIP_INTERFACE ) (?)
    Length : 0x02
    DATA bit0: DCD
    bit1: DSR
    bit2: BRK
    bit3: RI
    bit4: FRAMING (error)
    bit5: PARITY (error)
    bit6: OVERRUN (error)


    というもののようだ。
    本来なら、接続したときに DCD=1,DSR=1 にして これを送り、スタータスが変わったときにも送る。だが、いまのところ 対応するコードはまったくない。

    ところで、いくつか修正しないといけない。

  • 内部 3.3V レギュレータの扱い。

    これは、外部から 3.3V を供給するとき以外は disable にしてはいけない。そして、外部から 3.3V を供給するときでも動作自体は支障がない。

    disable にしたりしなかったり適当だったので、しないように 変更する。

  • UDINT=0

    デバッグの都合で、main のコードに こういうのを入れてしまっている。本来なら usbInit() でやるべきことなので、修正する。実をいうと GPIOR2=0 もしておかないといけない。

  • TPI/PDI』の記事で書いたように USBasp を拡張可能なようにしようと思う。
    具体的には、isp.c で定義されている 関数を メソッド化 (C なので オペレーション を定義した 構造体)。そのままでまずい一部のものは、ちょっと変更する。

    FUNC_CONNECT で value_h を プロトコルバージョン とみなし 2 だったら value_l によって メソッドを変える。予定では 2 が TPI 3 が PDI (1 は ノーマルの別チャネルとか)

    --- 1.1c 以降 ---

  • 1.2 にすればと思いつつ 1.1 のままにしてしまった。

    いちおう serial も他の相手と通信できることを確認した(9600 bps だけだが)。usbasp2 も フレームワークを変えたが、ロジックは変えていないので当然のごとく動いた。

  • serjtag はやはりちゃんと動かしておきたい。DTR をサポートできるようになったので、DTR = 0(H レベル) + BREAK で serjtag モードに入るとかしようかと思う。

    あと、USBasp 拡張で TPI/PDI のコードも入れてみたいが、どうしよう。

    作るとしたら こんな感じか。

      PD2(RXD) --------+-- 300 ---- PDIDATA/TPI_DATA
      PD3(TXD) --------+

      PD5(TCK) ------- 300 -------- PDICLK/TPI_CLK

      PD4? ------- 300 -------- TPI_RESET

      とりあえず抵抗入れとけばよい?

    • TPI の場合相手は 5V 電源。XMEGA だと 最大が 3.6V ぐらいで 最低は 1.6V ? -- だっけか。
      1.6V はそもそも無理だとして 2.5V 以上 を前提にしておく。相手にも自分にもクランプダイオードは入っている。それで 0.3V ぐらいの電圧差分は吸収できる .. として 電流がながれたときの電圧降下で 電圧差を吸収。

    • AVR は 結構電流を流せるのだが、問題は 相手もしくは自分の電圧が上がってしまうこと。5 mA までにしておけば まぁ大丈夫だろうということで PDICLK/TPI_CLK は 300 Ω。

    • PDIDATA/TPI_DATA の場合はさらに出力の衝突の可能性がある。5V 差 でも 300 Ωなら 16.7 mA なので 問題にはならないはず。

    • TPI_RESET については 相手がプルアップしているだけ。Hi-Z / L で駆動するなら 直結でも良さそうだが、一応抵抗をいれておく。

    • ちゃんとしたければ レベルシフタを入れる。.... として 回路はともかく制御用の信号線は考えておかないと。-- Enable と 送信/受信切り替え ?

    ここの更新をサボッていた。現在 1.4 まで来た。だいたい UM162ボード用の更新。
    1.4

    • angle_loader の m32u4 版は 2KB を超える。これだけ超えるのが嫌なので、割り込みベクタを削った バージョンにして、すべてが 2KB 以内になるよう変更した。

      こうするのには、startup ファイルの変更が必要で、avr-ld を直接使うことになる。
      そうすると GCC やら avr-libc やらのパスが必要になって、設定が面倒になる。

      でも 100 バイト以上減るのは魅力で 対応することにした。


追記: 秋月 の arduuino もどき AE-ATmega が出てきた。

    基板の単価が 150円と格安。パーツセットも出るらしいから、数が出るだろう。
    eJackino と似てると思ったが、よくよく見たらパターンが同じっぽい。上の ユニバーサル基板用のコネクタがないだけだった。

    他にも相違点はあるようだ。(参考 → kosaka さんの記事)。
    ただ パターンの取り回しが良く似ているから、改造とかは同じような感じでできる。



    Teensy 1.0 互換でなく、AE-UM232R 互換にしておけばよかったかも。-- 次作るときのために検討しておこう。



    これが AE-UM232R まわり。



    配線を整理するとこうなる。

    で、UNO はこうなっている。

    PB1 (SLCK) ISP コネクタ
      PB2 (MOSI) ISP コネクタ
      PB3 (MISO) ISP コネクタ
    PD2 (RXD) arduino TXD
    PD3 (TXD) arduino RXD
    PD4 RX LED (L active)
    PD5 (XCK) TX LED (L active)
    PD7 (HWB) arduino DTR


    これも合わせるとこんな感じか。


          AE-UM232R 案
    TX TXD PD3(TXD)
    RX RXD PD2(RXD)
    DTR DTR# PD7(HWB UNO:DTR)

    TX_LED CB0 PD5(XCK UNO:TX_LED)
    RX_LED CB1 PD4(UNO RX_LED)

    X3 1 CTS# PB3(MISO)
    2 DSR# PB1(SCK)
    3 DCD# PB2(MOSI)
    4 RI# PB0(SS)

    RST RESET (パターンカット)

    RST は、VCC に直結されてしまっている。不要だと思うし、パターンカット前提で考える。
    無接続のピンは好きなようにわりあてるつもりだったが、無理そうなので NC でまず検討。

    ...とはいえ 配線は自分のスキルでは厳しい。

    追記:なんとか出来た。『AE-UM232Rピン互換ボード』の記事参照

デバッグの記録 ver 1.4 serjtag の動作確認

    1.4 では、DTR=1 で serial / DTR = 0 で serjtag という風にして 1 つのファームウェアで 通信機能とライタ機能を両立させることにした。

    で、serjtag の動作確認を avrdude-serjtag-04k で確認してみることにした。

    実を言うと serjtag 自体を動かすのは初めて。ただし serjtag の拡張機能に ADC 機能があるので それは、32u4 のボードで確認している。ADC 機能の 通信部分は avrdude から借用したのものなので、serjtag のプロトコルのみが動作未確認。

    とにかく、やってみたところ、ちゃんと動いた。

    $ avrdude.exe -c serjtag -P COM13 -p m32u2 -U flash:w:angel32u2_16M.hex

    Found programmer: Id = "SERJTAG"; Revison = 21
    avrdude.exe: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.00s

    avrdude.exe: Device signature = 0x1e958a
    avrdude.exe: NOTE: FLASH memory has been specified, an erase cycle will be

    performed
    To disable this feature, specify the -D option.
    avrdude.exe: erasing chip
    Found programmer: Id = "SERJTAG"; Revison = 21
    avrdude.exe: reading input file "angel32u2_16M.hex"
    avrdude.exe: input file angel32u2_16M.hex auto detected as Intel Hex
    avrdude.exe: writing flash (32760 bytes):

    Writing | ################################################## | 100% 11.83s

    avrdude.exe: 32760 bytes of flash written
    avrdude.exe: verifying flash memory against angel32u2_16M.hex:
    avrdude.exe: load data flash data from input file angel32u2_16M.hex:
    avrdude.exe: input file angel32u2_16M.hex auto detected as Intel Hex
    avrdude.exe: input file angel32u2_16M.hex contains 32760 bytes
    avrdude.exe: reading on-chip flash data:

    Reading | ################################################## | 100% 13.36s

    avrdude.exe: verifying ...
    avrdude.exe: 32760 bytes of flash verified

    avrdude.exe done. Thank you.

    こんな風に出力されている。

  • -c serjtag -P COM13
    という風に ポートの指定も合わせてする。

  • 書き込んだ後、ただちに動作させたかったら -E reset を追加する。

  • write 11.83s / verify 13.36s というのは、遅いかも。現状では、ソフト SPI だし、delay の調整してないし こんなものだろう。

    ハードウェア SPI にして、delay の 設定を (プロトコル上の意味も含め)再検討することにしよう。
posted by すz at 21:59| Comment(119) | TrackBack(0) | USB162

2007年12月17日

秋月フルカラーLCDメモ

秋月で 単体 300円の格安な
400x96フルカラーLCD
が売られている。(インバータ付きのセットは、1000円)

詳細資料がないのでこの値段なのだが、最初になる研での解析が行われ、さらに xcrosgs2wy 氏によるより詳細な解析も行われている。

これでどのように制御すれば良いかについてはわかる。しかし、0.5 mm ピッチのコネクタの扱いが大きな壁だ。

ちなみにフレキケーブルは、Aitendo で 480円で購入することは可能だ(在庫は36P 80 mm)。日米商事とかジャンクなら 20円で手に入るかも知れない。
しかし...フレキが手に入っても、そのフレキを半田付けしなければならない。

ためしにフレキのコネクタをはずし、直接 ケーブルを半田付けしてみた。0.5 mm ピッチのチップを半田付けするよりはるかに難しい。-- なにしろランドよりケーブルのほうが太い -- 私の技術では、0.5 mm ピッチで全部半田付けするのは無理というのが結論。

ただ、空き - 2 本 - 空き のケースならなんとか半田付けが可能だった。要するに、1(TEST),2(NCLK),4(HSYNC),5(VSYNC),8(B5),9(B4), 15(G5),14(G4),22(R5),23(R4),29(VCPP_ADJ) だけなら私でも半田付け可能。

電源系は、秋月の資料(pdf)にあるとおり、チップ抵抗/チップコンデンサに直につければよいので問題ない。
秋月の写真をみると、アナログ系の電源は、コンデンサの前に 1.0 Ωの抵抗と 10uH のコイルが入っている。目的はノイズ低減。安定化した電源を使えば多少ノイズがあっても大丈夫そうだ。

さて、次の問題は、±9V の電源。これは RS232C レベル変換ICを使えば簡単そうだ。チャージポンプのコンデンサは、普通 0.1uF を使うが、出力が足りなければ 数 uF にすればよいだろう。(ADM3202ANの資料では、10uF まで OKと書いてある)

注意)±9Vでは、フレームレートを高くする必要があるらしい。今回のように遅いフレームレートの場合±12Vにするのが良いとのこと。ひょっとしたら ±15V の方が良いのかも知れない。
xcrosgs2wy 氏 の ページが参考になりそう。
といっても、既に回路を組んでしまった。-- どうしよう。


(ここまでの写真掲載予定)

AT90USB162 を使っての制御方法(案)

データは B2,G2,R2 の合計 6bit しかない。HSYNC/VSYNC を加えての 8bit を PORT(D or B) に割り当てて、タイミングも含めて PC から送ってもらえばよいだろう。

1番ピンから順に割り当てるとして、

Port 7 HSYNC
Port 6 VSYNC
Port 5 B5
Port 4 B4
Port 3 G5
Port 2 G4
Port 1 R5
Port 0 R4

でどうか。

このやりかただと、1フレーム(最小 410x96 clock)に 約 40KB 必要。CDC を使っても 最大で 280KB/sec ぐらいになるので、7fps ぐらいになるだろう。7fps あればなんとか見れるのではないか? ダメなら 専用の Bulk OUT エンドポイントを割り当てることで 2-3 倍になると思う。ただし、ドライバー・ライブラリをどうするのが良いかについては知らない。

ちなみに、8bit だけなので、FT245RL を使うという手もある。CLK は(Mprog で設定すれば)、FT245RL から取れるので、Flip-Flop 1 個あればインターフェイスできそうだ。(タイマIC を使うという手もある。) Windows からしかまともに使えないが、D2XX インターフェイスを使えば 1M Bytes/sec 可能なのがメリット。

さらにいうと、AT90USB162 ではなく、普通のATmega で制御してゲームをはじめとして、いろいろなものを作ることは可能だろう。もちろん、そういう使い方でも、AT90USB162 を使うことができるはず -- PC でプロトタイプを作り、AT90USB162 で ターゲットAVR のプロトタイプを作れるというのが AT90USB162 のメリットと言える。


注意点

1) NCLK を長時間停止したままにしていると、液晶が損傷するらしい。1秒ぐらい? PC からデータが来ていないときは、 モードを移行して NCLK を ON/OFF するようにする必要がある。

その他の機能について

USB を使うなら LCD 側の電源を On/Off できたほうが良いと思う。LCD の +5V 入力を一ヶ所に集めて PNP トランジスタ か Pch MOS FET でスイッチする。突入電流が流れないように、LC フィルタが必要なはず。インダクタは、千石の LHLZ06NBの33uH 〜 100uH が良いと思う。

また、VCPP_ADJ は、0V 〜 3V 程度でよいらしいので、これも PWM で作ると良いのではないかと思う。PWM 可能な端子に LC フィルタを付けて VCPP_ADJ に供給すればよい。インダクタはいつもの LAL02NA470K(47uH)、コンデンサは 10uF で良いだろう。cutoff は 7.3 kHz なので 1/1 プリスケール(62.5kHz@16Mhz)で十分そうだ。ただ、電流が流れすぎないかちょっと不安。ポートと LC フィルタの間に 100 Ωぐらいの抵抗を入れておくと良いかも知れない。

追記:16bit化の案

FT245RL で 1MB/sec でるならば、1ピクセルに 2バイト使っても 12.5 fps で表示できることになる。

AT90USB162 では専用ドライバがない限りここまでの性能は出ないし、半田付けが無理とみて、8bit 版の案を紹介したのだが、16bit 化についてもついでに紹介してみる。


            ラッチ
Port 7 SELECT     空き
Port 6 VSYNC HSYNC
Port 5 B5 B3
Port 4 B4 B2
Port 3 G5 G3
Port 2 G4 G2
Port 1 R5 R3
Port 0 R4 R2


ラッチを1つ追加して、SELECT = 1 のとき ラッチにロードすることにする。 で、SELECT = 0 のときだけ NCLKを↓する。こうすることで 4096 色化が可能だと思う。

もし、AT90USB162 を使うならば、Port を 2 組(D and B) 使う。HSYNC を 最初のポートの bit 7 と 2つ目のポートの bit 6 両方につないでしまう。これでモード切替えるだけで、8bit 版と 16bit版の両方に対応できるようになるはず。

ちなみに HSYNC /VSYNC を内部で生成して、色をさらに割り当てるのは難しい。1MB/sec 出すつもりならば 16MHz でも 16 cpu clock しかないのだ。
posted by すz at 15:58| Comment(2) | TrackBack(0) | USB162

2007年12月13日

CDC-ACMドライバチューニング

Linux の CDC-ACM ドライバのチューニングが完了した。

2.4 カーネル用だけではなく、2.6 カーネル用も作成できたので、公開しておく。2.4 用は、2.4.31前後に対応。2.6 用は 2.6.17と2.6.23に対応(しているはず:間のバージョンは若干の手直しが必要)

一応動いたが、安定して動くかどうかは怪しい。特に open/close 時 や USB 切り離しのときに なにか問題がおきるかも知れないので注意。

acm-driver-0.1.tar.gz


注意)このドライバを更新情報はこのページに載せますので、最新版を使うようにしてください。なんの保証もできませんが、問題があれば直します。

おねがい)このドライバのバグを見つけたら、このページにコメントをお願いします。

USB162(test1/test2 FW)を使っての性能評価

オリジナルはあまりにひどい性能なので、Windows XP と性能を比較してみた。ちなみに 2.6 版は 玄箱/HG ! での評価。

pingpong テスト

N バイトを write してエコーバックされてくるおなじ N バイトのデータを read するスループット。



おもしろいことに、2.4 版と Windows XP の特性がほとんど同じになった。2.6 版は、飛びぬけて速いところがないかわりに、リニアに性能があがる。2.4 や XPは、基本的にギクシャクしながら動いていて、つぼにはまると高い性能がでる。それに対して 2.6 はなめらかに動いているというところか。

pipelining テスト

処理データ量は pingpong と同じだが、write と read を 3回分ずらしてパイプライン処理にしたもの。



このようにソフトをチューニングすると、2.6 は安定して高い性能になる。スケジューリングの勝利と言えそうだ。

read スループット テスト

ADC 取り込みのシミュレーション、USB162 の test2 ファームウェアを使い定期的にデータを発生させる。データ量は、1サンプリングあたり4バイト。ホストは、1KB単位で read をかけている。



2.6 も 2.4 も同じ性能になった。このテストでは、バッファリングがしっかりしていれば、スケジューリングはあまり関係なくなる。

write スループット テスト

こんどは逆に DAC への出力のシミュレーション。ホストは 1KB 単位で write をかける。write が終了したら USBに送られたことを確認せず終了しているので、実際より若干高めの値になる。



2.6 と 2.4 は同じ性能。同じバッファ量なので当然かも知れない。バッファに余裕があるので、ピーク性能まで直線的に性能があがる。XP はバッファが若干足りないのかも知れない。

write + read スループット テスト

1KB 単位で write して read する。ここでも パイプライン処理にしていて、1 回ずらしている。



これもまた、2.4 2.6 ともに同じ性能。そして XP より若干良い。

AVR-CDC 編

さて、AVR-CDC の性能はどうなったのか? Windows XP と比べてみることにする。

最初は test1/test2 ファームウェアを移植するつもりだったが、コンパイル環境を gcc-4.2 ベースにしたら、AVR-CDC が動かなくなってしまった。しょうがないので、"p" コマンド → "S" を使って pingpong/pilelining テストのみをすることにした。

pingpong テスト



8バイトまでのデータは、1パケットの遅延時間に依存していると言える。結果を見ると、3 つに分かれる、Linux-2.6 オリジナル・チューンド ドライバ 、Linux-2.4 チューンド・Windows XP 、2.4 オリジナル。2.6 が良いのはスケジューリングが良いためで、2.4 オリジナルが悪いのはドライバの出来が悪いため。

16 バイトを超えると、スケジューリングの影響は減り 2.4 オリジナル以外はだいたい同じ性能に落ち着くようだ。

pipelining テスト



2.4 オリジナルは論外として、おおざっぱに言うと Windows vs Linux という感じ。Windows はピーク性能が高く、Linux は、小さなI/O サイズでの性能(レスポンス)が良い。ピーク性能とレスポンスの両立は難しい。設計ポリシーの違いと思えば良いかも知れない。

AVR-CDC まとめ

AVR-CDCでは、2.4 オリジナルドライバの性能は論外に低かった。チューニングしたドライバに変更すると 2倍〜3倍程度性能が上がる。2.6 の場合は、AVR-CDCを使うだけなら、ドライバを変更しても性能は変わらない。

AVR-CDC スループット

AVR-CDC 用 test2 fw をビルドできるようになったので、スループットを測定してみた。Linux のドライバは、チューニング版。

read スループット テスト



一応両者とも 4kHz = 16KB/sec のピーク性能。

Windows XP は綺麗な曲線になったが、Linux は 2.6 でさえガタガタ。これは CPU スケジューリングではなく、1ms の間にパケットを1個読むのか2個読むのかの判断がうまくないためだろう。

write スループット テスト



今回は、write 終了後コマンドを送ってそのレスポンスを待ち合わせるようにした。すなわち、ズルい値ではなく正しい性能。

2.4 では、3kHz = 12KB/sec で頭打ちだが、2.6 と Windows は 16KB/sec 以上に伸びている。また、おもしろいことに特性が似ている。たぶん両者とも最高の処理になっているのだろう。

write & read スループット テスト



これが重要なのだ。最高にソフトウェアをチューニングして、JTAG / SPI の処理をさせたらどうなるかの指標になる。

2.4 と Windows は、2kHZ = 8KB/sec での write & read が出来ている。これも帯域としては、16KB/sec ということになる。なぜか 2.6 は若干性能が低い。

この性能だと、USI ではなく SPI を使った AVR ライタを作るとすれば、4B の write & read で 1バイトを読み込めるので、 2KB/sec ぐらいで ベリファイできるだろう。(Write は 2倍弱 か?)USI or Port 制御だと、1割か2割落ちそうだ。

また read で 16KB/sec 出ている。2 バイトのデータをキャプチャーするとすれば、5K sps ぐらいなら取り込めそうだ。ただし、データの取りこぼしは絶対起きる。時刻 or シーケンス番号の情報を載せた方が良いだろう。どうやってそれができるか良くわかっていないが、タイマーが2つあるのだからなんとかなるに違いない。時刻情報が含まれていて、くり返し波形をキャプチャーするならソフト次第で もっと高い周波数(80k sps -- 40kHz ぐらい?)の波形が見れるはず。
posted by すz at 21:24| Comment(0) | TrackBack(0) | USB162

2007年12月11日

Linux CDC-ACM ドライバの性能

いままで、AVR-CDC の性能を調べてきたが、Windows に比べて Linux が遅い場合が多かった。単に Linux のマシンのスペックが悪いからだと思っていたのだが、どうも違うらしい。

USB162 を動かしてみると、Windows に比べて Linux が圧倒的に遅い。どうもドライバの作り自体に問題がありそうだ。

ちょっと、Linux ドライバのソースを眺めてみた。

linux-2.4 ACM ドライバ

urb というデータ構造を使って、I/O を行っている。その urb は read/write に1つづつアロケートし、バッファのサイズは エンドポイントの パケットサイズ。

要するに、read/write ともに 32バイト単位で I/O を行い、それらの I/O が完了しないと、次の I/O ができない。

USB は、1ms 毎に処理を行うようだ。そのようなデータ構造だと、どうやっても 32KB/sec を超えられないように思える。

では、他のドライバはどうなっているのだろう?

linux-2.6 CDC-ACM ドライバ

Linux-2.6 ではどうなっているのか見てみた。

ACM_NRU,ACM_NWB という define があり、それぞれ 32,2 になっている。
write については、urb は 1つだが、ACM_NWB 数 の バッファを切り替えている。バッファのサイズは、エンドポイントの パケットサイズ。

よくわからないが、バッファが 2 つあるので 高速そうな感じだ。

後記:
バッファを用意して、write が終わったらすぐに次の write を出せるようにしているだけだった。多重に write を出さなければ、高速にはならないようだ。重に write を出すときは、flags にUSB_QUEUE_BULK を指定する必要がある。

read については、urb を ACM_NRB数 生成している。そして、バッファのサイズは、エンドポイントの パケットサイズ x 2 。--- パケットサイズ にあわせなくとも良いらしい。

2.4 カーネルと比べれば 2 倍のバッファサイズで 16倍の多重度ということになる。これなら全然性能が違うのではないか?

linux-2.6 FTDI ドライバ

枯れていると思われる FTDI のドライバはいったいどうなっているのか? ついでに見てみた。

write では、tx_outstanding_urbs という変数があり、その最大値が 42 ! になっている。バッファのサイズは、64 バイト - αのようだ。

read では、urb もバッファも 1 つしかないが、バッファのサイズは 512 バイト。

チューニングしてみる1

readsize を変更しても動かなくなることはなさそうなので、とりあえず readsize を 4倍、16倍にしてみた。



readsize を 4倍の 128バイトにすると 性能が数割あがった。16倍にしても、若干上がるだけでそれ以上の性能向上はないようだ。

...といっても基本となる性能は、Windows の 50kHz のレンジと比べれば 1/10 程度。

では、write もサイズを大きくしてみることができるのか? 他のドライバは、そういうコードになっていないので、無理という気がするが、まぁやってみることにする。



結果は、read と良く似たかんじ。4 倍にするだけでずいぶんと性能があがる。16 倍にしたからといって、大幅に性能があがるわけではない。

... それは良いのだが、16 倍は実はおかしい。1 回測定すると 2回目が動かない。抜き差しして初期化すると 1回の測定が通った。やはりなにかあるらしい。

さて、オリジナルの性能は、最高で 4KHz 程度。1 回に 4バイトなので、1ms 毎の平均パケットサイズは、16バイトにしか過ぎない。USB162 の方は、32バイト詰め込んでいるはずだ。... ということは 動いていないときがあるということだ。

サンプリングしたデータは、タイマ1 の値なので、どのように動いているのか見ることができる。



このグラフは、サンプリングした時刻とサンプリング数の関係。HOST がデータを read しない時間帯があれば、横ばいになる。20 ms の間に 6 回そういう時間帯があったということ。ちなみにこのデータは、readsize を 128 バイト、8KHz サンプリング(1ms あたり 32バイト)でのデータ。常に read しているわけではなく、ときどきとまっていると見てよいはずだ。

Linux-2.6.17 CDC-ACM ドライバの性能

Linux-2.6 のマシンは、玄箱/HG しかもっていない。これでどうなるか見てみた。



read は、Windows 並の性能が出ている。それに対し write は、8k Hz (1ms に 32バイト) が上限になっている。ACM_NWB を 16にしてみたが、性能は変わらなかった。read はちゃんとできているが、write は、FTDI のような処理にしないと性能が出ないように思える。


おわりに

結論としては、Linux-2.4 の CDC-ACM ドライバの出来は悪い。2.6 になれば read は良くなっているが、write はさほどでもない。ftdi のように ちゃんとしたものしなければ、Windows 並の性能にならない。

最初に作ろうと思っている、ADC からデータを吸い上げる装置は 48kHz 16bit x 2 までなら Windows XP か Linux-2.6 を使えば、CDC でいけそうだが、次に作ろうと思っている、JTAG とか SPI のような write して read するアプリケーションの場合、Linux は遅いことになる。

どのようにドライバを改造すればよいか、少し判ってきたような気がするので、当面は CDC にこだわってみようと思う。

(続き)

チューニングしてみる 2

まずは、2.4 の CDC-ACM ドライバの write をFTDI のコードを参考にして、チューニングしてみる。

バッファのサイズはそのままで、多重に I/O をかける。そのための urb は 16 個で試してみる。

write の要求が来たら、urb がある限り usb_submit_urb するだけ。urb の管理が面倒だが、ロジックとしては簡単そうだ。




すこし変なところがあるが、Windows 並の 250 KB/sec ぐらい出るようになった。


read は、実はよくわからない。(多重に read をかけていない)オオリジナルがどうやっているか? ちょっと整理してみる。


○初期化(xx_open):
無条件に read をかける。

○read 完了(callback):
throttle == 0 の間、tty_insert_flip_char で
     read したデータを tty の flipbuf ? に移動
     (移動している間に throttle == 1 になる場合あり)
throttle == 1 の場合は、urb にデータを残して return
throttle == 0 の場合、全部を移動したので
     次の read をかける。
○throttle = 0 の変化
xx_throttle callback 関数が call される。その中で
read 完了と同じ関数を call して 未処理の データを
tty の flipbuf に移動。


まあなんだか良くわからないがこんな感じだ。

filpbuf に移動しきれなかった場合、read がかけられないので、性能が低下しているように見える。

read を多重に出すというよりは、read 済みの データのバッファリングをなんとかすれば性能が出るのではないかと思えてきた。urb を多数もっていて、リングバッファのように使うコードにして、read 多重度 1 で制御するようなコードを作ればなんとかなるような気がしてきた。

多重度 1 ではダメだった。多重度 N で制御できるようにした上で、全体の URB 数 16 , 多重度 8 ぐらいにしたら、性能が出るようになった。


おわりに その2

いまさら、2.4カーネルの1ドライバのチューニングの話を書いてもしょうがないので、これで終わりにする。ただ、2.6 カーネルの CDC-ACM ドライバもイマイチなことは判ったし、チューニングの方法もだいぶわかった。いずれのドライバもちゃんとチューニングすれば、Windows と同等の性能になる。

目安としては、read/write/write+read とも 帯域はだいたい 250KB/sec ( write+read の片道の性能は 1/2)ぐらい。bps にすると 2M bps にすぎない。USB162 + CDC を使った場合、それ以上の性能を出すのは ホスト側にとって厳しい。

ADC の取り込み/DAC への出力なら、48KHz 16bit x 2 サンプリングが上限。...だが 取りこぼしが出そうなレンジ。44.1 kHz あたりが無難そうだ。

JTAG /SPI なら、1M bps での write+read が上限になりそうだ。

追記

一応動いているようなので、Linux-2.4 ドライバと 性能グラフ



ソースコード: acm.c
パッチ: acm-2.4.31.patch.gz

コメント:

○このソース は、2.4.31 - 2.4.35 で同一なので、2.4 最新版でも使える。

○USB162 でしか試していないので、AVR-CDC でも試す予定。
posted by すz at 06:24| Comment(1) | TrackBack(0) | USB162

2007年12月10日

usb162-0.1

いままでのコードは、とりあえず動くことだけを目指したものだった。そろそろ動いてきたので、リリースに必要だと思う変更をして version 0.1 として usb162-0.1.tar.gzを公開する。

ライセンス

とりあえずライセンスは、GPL にした。もっと自由に使ってもらえるライセンスにしたいとも思ったのだが、全部を自分で作ったわけでもないので、無理かも知れない。

それ以前に、勝手に AVR-CDC の ID を使用している。まずいかも。

構造の変更

いままでのコードをベースに、できだけきれいな構造にした。



desc.h    -- デスクリプタ定義で使う define など
desc_cdc.c -- CDC 用 デスクリプタ定義

cdc162.h -- CDC の API 定義 (usbcdc_init など)
cdc162.c -- CDC の処理

usb162.h -- USB 一般の 定義
usb162.c -- USB コントロール処理

usbconfig.h -- 全体の定義



こんな感じ。ちなみに usb162 の処理は、(できるだけ)ディスクリプタ自体をみて処理をするようにしている。グローバルな定義の数を減らすのが目的。

ソフトリセット

実はこれが最も大変な話だった。いままで USB RESET がくると CPU もリセットするようにしていたが、EEPROM を使ったデバッグをしたりすることで、遅延が大きくなり Windows で認識されにくくなっていた。

そのため、USB RESET での CPU リセットをしないようにして、RESET の処理を作り直すことにした。

まだ変な気もするのだが、一応動いているので、とりあえず FIXしておく。

初期化のシーケンス(Windows XP)


aa aa aa aa USB RESET
aa aa aa aa USB RESET
80 06 00 01 GET_DESCRIPTOR (Device)
aa aa aa aa USB RESET
00 05 02 00 SET_ADDRESS
80 06 00 01 GET_DESCRIPTOR (Device)
80 06 00 02 GET_DESCRIPTOR (Config)
80 06 00 02 GET_DESCRIPTOR (Config)
80 06 00 03 GET_DESCRIPTOR (String)
80 06 02 03 GET_DESCRIPTOR (String)
80 06 00 03 GET_DESCRIPTOR (String)
80 06 02 03 GET_DESCRIPTOR (String)
80 06 00 01 GET_DESCRIPTOR (Device)
80 06 00 02 GET_DESCRIPTOR (Config)
00 09 01 00 SET_CONFIGURATION
a1 21 00 00 COMM_GET_LINE
21 22 00 00 COMM_SET_CONTROL


初期化のシーケンス(Linux 2.4.31)


aa aa aa aa USB RESET
aa aa aa aa USB RESET
00 05 3b 00 SET_ADDRESS
80 06 00 01 GET_DESCRIPTOR (Device)
80 06 00 01 GET_DESCRIPTOR (Device)
80 06 00 02 GET_DESCRIPTOR (Config)
80 06 00 02 GET_DESCRIPTOR (Config)
00 09 01 00 SET_CONFIGURATION
00 09 01 00 SET_CONFIGURATION
21 22 00 00 COMM_SET_CONTROL
21 20 00 00 COMM_SET_LINE


Windows は、まずは GET_DESCRIPTOR を行って、エンドポイントのサイズを取得する。その後 いったん USB RESET を行ってから設定に入る。Linux では、GET_DESCRIPTOR を行わずに SET_ADDRESS し、それから 8バイトで GET_DESCRIPTORを行い、エンドポイントのサイズを知り、再度取り直している。Linux がなぜ 2回 SET_CONFIGURATION をしているのかはまだ判らない。

POWERON RESET そのものや、EEPROM の 初期化をしているので、USB RESET は最初に1回来るのはやむを得ないのだが、2 回目の理由はわからない。Linux の dmesg を見ると、SET_ADDRESS を投げているはずなのだが、USB162 側は認識していない。

EEPROM_DEBUG を undef するとレスポンスが速くなってエラーなしに接続できているようだ。でも情報が取れないので正確なところは判らない。


サンプルプログラム

サンプルはいままでどおり echo するだけの test1.c と 定期的にサンプリングする test2.c の2つ。それぞれの性能を測定するプログラムを perf/perf_test.c と perf/perf_test2.c に付けている。

おわりに

実用として使えるプログラムは、まだない。いままで Windows の性能ばかり書いて Linux の性能を書いていないことも関係するのだが、Linux(2.4.31) の ACM-CDC ドライバの性能がすごく悪い問題がある。

そもそも AT90USB162 を使う理由は、高速なものが作れることを期待したため。高速でなければ、AVR-CDC でも良いわけだ。そういうわけで、Linux でも高速に使えるものでなければ、実際の装置を作る気がしない。

次のステップは、Linux の ACM-CDC ドライバの性能がなぜ悪いのかを調べててチューニングする。その結果 速くなれば、CDC を使った実際の装置を作ろうと思う。そうでなければ、速くできる方法を探すつもり。
posted by すz at 23:57| Comment(0) | TrackBack(0) | USB162

2007年12月06日

ドライバの設計とテスト(3)

だいぶ動いて来たので、そろそろ 性能を見てみることにする。

やりたいことは、定期的にサンプリングしたデータを PC に取り込むような装置を作りたいということなので、それにあわせたテストをしてみる。

一回のサンプリングで、16bit 2ch 分のデータを取り込む。今は ADC が付いていないので、データとして タイマ1 の値を使う。-- こうしておいて値を調べれば、どれぐらいちゃんとサンプリングできているか分かるはず。



これは、その結果。サンプリングレートが低いときは、ちゃんと送れているが、高くなるにつれて実効サンプリングレートが落ちてくる。最後には頭打ちになる。

これを見ると、52000 Hzぐらいで頭打ちになっている。K bytes/sec で言うなら 200 kB/sec あたりが上限ということだ。

ただし、サンプリングレートと実効サンプリングレートが一致しないということは、データを取りこぼしているということだ。シリアルの場合は時間情報も一緒にいれるか .. それとも AUDIO クラスにちゃんと対応するかしないと 低いレートでもまともに使えないかも知れない。まだまだ工夫が必要だ。

参考までにここまでのコード usb162-test3.tgzを提示しておく。作成途中なのでライセンスは設定しない

ちなみに、このテスト用に ファームウェア(test2.c)と 測定プログラム(perf_test2.c)を新たに作っている。


エコーバックの性能



pingpong は、IO SIZE を write して、IO SIZE を read する性能。性能表示は Bytes/sec で片道分。(帯域は 2倍使用している)。

pipelining は、pingpong の read を N ずらしたもの。レイテンシが隠れるので、普通は性能が上がる。

おもしろいことに、pingpong の場合、32バイトのときだけ飛びぬけて性能が高い。pinelining すると、性能が安定して出るようになる。... といっても 17K bytes/sec 程度しか出ていない。もっとチューニングが必要だ。

追記
上のテストは、BULK OUT(PC→USB162)の設定が 32バイトDUAL_BANK のときのもの。これを 64バイト ONE_BANK にしてみた。



なんだか変な特性になった。pipelining のときも 32,64,128,256 バイトのときに性能が高くなる。そして上限がだいたい 64KB/sec +α。1ms 毎に 64 バイト 送信(OUT , PC→USB162) する性能がだいたいの上限を決めているように思える。

WRITE ONLY テスト

では、送信のみしたときはどうか? (USB162が)定期的にサンプリングして、データを読み込むテストをしてみた。これは、DAC データを送るような用途。OUT の設定を 64バイトx1 と 32バイトx2 で試してみた。



結構でるようだ。最高で 250 KB/sec ぐらい。ということは、1ms 毎に 64 バイトしか PC側が送らない。と思ったのは間違い。

そして、32バイトx2 の方が性能が良い。連続で受信する場合は OUT のサイズはあまり関係なく、バッファリングしている点が有利なのだろう。

ここまでのコードは、 usb162-test4.tgz。しつこいようだが、作成途中なのでライセンスは設定しないので注意。次あたりのバージョンで、ちゃんとライセンスできるようにしようと思う。

追記 write+read の性能



write して read する場合の性能をとることができた。だいたい 30kHz で 4バイトを writeしてread することができる。帯域としては read/write の合計で 250KB/sec ぐらい。
posted by すz at 21:05| Comment(0) | TrackBack(0) | USB162

ドライバの設計とテスト(2)

ターミナルソフトで動くようになった。(Linux で確認)
気を良くして、ダブルバンクにも対応。

エンドポイントの割り当て


エンドポイント サイズ UECFG0X UECFG1X
#0 CONTROL 8 0x00 0x02
#1 INTERRUPT IN 8 0xc1 0x02
#2 ----
#3 BULK IN 32(DUAL) 0x81 0x26
#4 BULK OUT 32(DUAL) 0x80 0x26


あまり詳しく書いてないのでわからなかったのだが、DUAL BANK にできるエンドポイントは、#3,#4 のみということが分かった。なので、番号を移動した。割り当てたメモリは、176 バイトのうち、144 バイト。32バイトしか余っていないので、BULK IN/OUT のサイズはこれ以上増やせない。

動作の確認 SETUP

EEPROM にログを残すようにして、どのような SETUP が来たかトレースしてみた。


Linux ACM ドライバの場合
 ↓ TYPE/REQUEST/VALUE(L)/VALUE(H)
00 05 5a 00 SET_ADDRESS (address = 0x5a)
80 06 00 01 GET_DESCRIPTOR (DEVICE)
80 06 00 01 GET_DESCRIPTOR (DEVICE)
80 06 00 02 GET_DESCRIPTOR (CONFIG)
80 06 00 02 GET_DESCRIPTOR (CONFIG)
00 09 01 00 SET_CONFIGURATION (#1)
00 09 01 00 SET_CONFIGURATION (#1)
21 22 00 00 SET_CONTROL_LINE_STATE
21 20 00 00 SET_LINE_CODING
--- Linux ドライバ 組み込みまで
21 22 03 00 SET_CONTROL_LINE_STATE
21 20 00 00 SET_LINE_CODING
--- ターミナルソフト起動まで
21 22 00 00 SET_CONTROL_LINE_STATE
--- ターミナルソフト終了


このような動きだった。SET_ADDRESS の前に たぶん GET_DESCRIPTOR が 来て USBのリセットが来ているはずだが、USBのリセットで CPU もリセットするようにしているので、分からない。

SET_CONFIGURATION も含めて 2 回づつ来ているのが気になる。なにかマズイところがあるのかも知れない。

動作の確認 TX/RX


ログデータ 送・受(バンク#) バイト数(UEBCLX)
41  受信(BANK=0) 1
01 送信(BANK=0) 1
40  受信(BANK=0) 0
21 送信(BANK=1) 1
60 受信(BANK=1) 0
01 送信(BANK=0) 1
40 受信(BANK=0) 0
21 送信(BANK=1) 1
60 受信(BANK=1) 0
01 送信(BANK=0) 1
61 受信(BANK=1) 1
21 送信(BANK=1) 1


これは、a a a と 3バイト入力したときのログ。ちゃんとエコーバックされる(= 正しくデータを受け渡しできている)のだが、なにか変。バイト数(UEBCLX) が期待したものと違うようだ。


ベンチマークとテスト

データを大量に送受信して、ちゃんと送ったデータがエコーバックされてくるかどうかを調べてみた。


テスト1) 4 バイト送受信 x 10回

いちおう動いた。しかし 2回目から動かない。

テスト2) 4 バイト送受信 x 200回

うごかない。100 回なら OK 。


まだまだダメみたいだ。次はこのテストを動かすことに目標にする。

(続き)

原因が分かって、まともに動くようになった。

2 回目から動かないのは、SET_CONTROL_LINE_STATE の後 0 バイトを HOST に送信する必要がある。これは usbcdc と同じ処ような理
にすることでクリアできた。

ちゃんと動かないのは、バイト数(UEBCLX)の意味を誤解していたため。UEBCLX は、バンク1,2 の合計のバイト数。RWAL フラグをみて FIFOCON の操作をするべきだった。

Windows でのテスト


Windows XP の場合
 ↓ TYPE/REQUEST/VALUE(L)/VALUE(H)
00 05 02 00 SET_ADDRESS (address = 0x02)
80 06 00 01 GET_DESCRIPTOR (DEVICE)
80 06 00 02 GET_DESCRIPTOR (CONFIG)
80 06 00 02 GET_DESCRIPTOR (CONFIG)
80 06 00 03 GET_DESCRIPTOR (STRING)
80 06 02 03 GET_DESCRIPTOR (STRING #2)
80 06 00 03 GET_DESCRIPTOR (STRING)
80 06 02 03 GET_DESCRIPTOR (STRING #2)
80 06 00 01 GET_DESCRIPTOR (DEVICE)
80 06 00 02 GET_DESCRIPTOR (CONFIG)
00 09 01 00 SET_CONFIGURATION (#1)
a1 21 00 00 GET_LINE_CODING
21 22 03 00 SET_CONTROL_LINE_STATE


Linux とシーケンスが少し違った。


テスト1) 4 バイト送受信 x 10回 OK
テスト2) 4 バイト送受信 x 200回 OK
テスト3) 32 バイト送受信 x 1000回
ダメ。read で 0 が返ってくる。
 ちなみに 31 バイト x 1000 回、
 33 バイト x1000 回は OK。


まだなにかあるようだ。

原因が分かった。データを送ったら、0 バイトを HOST に送信する必要がある。SET_CONTROL_LINE_STATE のときだけではなかった。そして、その処理は usbcdc でもやっていた。


参考までにここまでのコード usb162-test2.tgzを提示しておく。作成途中なのでライセンスは設定しない
posted by すz at 00:07| Comment(0) | TrackBack(0) | USB162

2007年12月04日

ドライバの設計とテスト(1)

最初の目標

まずは、なんでも良いから動かすことを目標にする。コードを綺麗にする(著作権のクリアとか構造化なんてもの)は後回し。

参考にするのは、AVR-CDC のコードと usbdrv あと Atmel のコードと さらに S. Salewski 氏の Free USB firmware。

ドキュメントは、USB の基本知識として HERO'S Download の AVRusb.ZIP に含まれる USB概説、AT90USB162 の日本語データシート。さらに(なぜか)MAX3420E のアプリケーションノートAN3690(日本語)。

AN3690 には、”少しわかりにくいですが、これが USB と HID仕様 のすべてです。” -- なんて自信たっぷりな記述がある。USB バストレースの図まで載っていて、イメージがつかめた。 非常に分かりやすいのでお勧め。

これらのリンクは、USB162メモにまとめておく。


プログラムの作成方針

Atmel のコードと S. Salewski 氏の Free USB firmware は、ひとつひとつの操作がマクロ化されていて、実際にどのような操作をしているのか分かりにくい。趣味に合わないので、マクロを全部なしにして、直接操作するようなコードで re-write することにした。

デスクリプターの記述については、AVR-CDC をベースにして楽をする。あと、ヘッダも AVR-CDC (と usbdrv) の一部を借りる。

割り込み処理は、USB装置割り込みのみを使用して、Atmel 流に ポーリングをベースにすることにした。

こんな感じで、まずは コードをでっちあげることにした。

外部インターフェイス

USB910 とかで使っている XXX_init() ,XXX_poll() ,XXX_getc() ,XXX_putc() を基本のインターフェイスにする。

これさえ揃えば、いままで作ってきた AVR-CDC を使ったコードを動かすことができるはず。

エコーバックさせるこんなプログラムで、テストする。


main() {
XXX_init();

for (;;) {
XXX_poll();
XXX_putc(XXX_getc());
}
}


エンドポイント処理 (OUT=受信)

エンドポイントの 1バイト データ取り出しは、(UENUM を設定した後)UEDATX を読み込むことでできる。XXX_getc() で直接この処理をすることにして、中間バッファを持たないことにする。

バッファが空でないことを知る方法は 2 つある。ひとつは、UEINTX の RWAL ビット、もうひとつは、UEBCLX(エンドポイントバイト数レジスタ)。

バッファが空になったら、UEINTX の FIFOCON をクリアすることで、次の受信ができるようになる。

受信したら、UEINTX の RXOUTI ビットがセットされる。FIFOCON をクリアする前にクリアしなければならないらしい。XXX_poll() で 常に RXOUTI ビットをクリアすることにする。(たぶん問題ないはず)

エンドポイント処理 (IN=送信)

OUT=受信と対のような感じ。

エンドポイントの 1バイト データ書き込みは、(UENUM を設定した後)UEDATX に書き込むことでできる。XXX_putc() で直接この処理をすることにして、中間バッファを持たないことにする。

バッファが一杯でないことを知る方法は 2 つある。ひとつは、UEINTX の RWAL ビット、もうひとつは、UEBCLX(エンドポイントバイト数レジスタ)。

UEINTX の FIFOCON をクリアすることで、バッファの送信が行われる。

送信したら、UEINTX の TXINI ビットがセットされる。FIFOCON をクリアする前にクリアしなければならないらしい。XXX_poll() で 常に TXINI ビットをクリアすることにする。(たぶん問題ないはず)

さて、受信と違うのは、いつ送信するかということ。1 バイトづつ送信することもできるし、フルになるまで溜めることもできる。

これは、スループットとレスポンスのトレードオフで決めるべきことなのだが、とりあえずは、XXX_poll() で送信してしまうことにする。

エンドポイント処理 (SETUP)

これが肝心なのだが、SETUP の処理は良く分からなかった。

プログラム自身はわりと簡単で、XXX_poll() で エンドポイント 0 に SETUP が来ていたら usb_process_setup 関数で処理させるぐらい。でも、どのような処理をすればよいかが分からないのだ。

とりあえずは、S. Salewski 氏の コードの処理をベースにして Atmel のコードの処理を参考にしてでっち上げた。

でっちあげるのは良いが、基本的なことを理解していないので全然動かせなかった。動かせる気もしなかった。MAX3420E のドキュメントを読んでようやく動かせる気になったわけだ。

装置割り込み

本当は、SUSPEND やら WAKEUP やら RESUME やらの処理をすべきなのだが、とりあえず RESET のみ対処することにする。

... と思ったのだが、USB のリセットで CPU をしまう方法があることが分かったので、割り込みを受けるだけのコードになってしまった。たぶん今のところ意味なし。

初期化

これも実によくわからない。#0 以外の エンドポイントの初期化や クロックのスタートなどが、最初ではなくて SETUP や割り込みで動くようになっている。

消費電力の低減や 再初期化のためにそうするほうが良いのかも知れないのだが、どういうタイミングで動くかもわからないので、最初にするようにした。手順を変えることで動かなくなるんじゃないかとか気を揉んだが大丈夫のようだ。

デバッグ方針

LED もなにも付けていないのでどうするか悩んだのだが、できるだけ EEPROM を使ってデバッグすることにした。

どうにもならなくなったら、FT232RL にシリアルを接続し、デバッグメッセージを 垂れ流すことにする。

プログラムの作成状況

現在コードの規模はこんな感じ


ソースサイズ:
62 usb.h
44 desc.h
7 usb162.h
283 desc.c
361 usb162.c
59 test1.c
816 合計

バイナリサイズ:
text data bss dec hex filename
1868 0 20 1888 760 test1.elf


機能的に足りないものもあるが、だいたい予定どおりか。

一応 Linux で USB デバイスとして認識できるところまでこぎつけた。

/proc/bus/usb/devices:

T: Bus=01 Lev=02 Prnt=03 Port=02 Cnt=02 Dev#= 41 Spd=12 MxCh= 0
D: Ver= 1.01 Cls=02(comm.) Sub=00 Prot=00 MxPS=32 #Cfgs= 1
P: Vendor=16c0 ProdID=05e1 Rev= 1.00
S: Manufacturer=www.recursion.jp
S: Product=USB-232
C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=acm
E: Ad=83(I) Atr=03(Int.) MxPS= 32 Ivl=100ms
I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=acm
E: Ad=81(I) Atr=02(Bulk) MxPS= 32 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 32 Ivl=0ms


dmesg:

hub.c: new USB device 00:1f.2-1.3, assigned address 41
usb.c: USB device 41 (vend/prod 0x16c0/0x5e1) is not claimed by any active driver.
usb.c: registered new driver acm
ttyACM0: USB ACM device
acm.c: v0.21:USB Abstract Control Model driver for USB modems and ISDN adapters


ACM ドライバまで組み込まれているが、実際に動かしていないし、たぶん動かない。

でもあと少しで動かせそうだ。

参考までにここまでのコード usb162-test1.tgzを提示しておく。作成途中なのでライセンスは設定しない

追記:
最初につくったこのプログラムを Linux で試してみた。

エコーバックされるので、一応動いているようだ。ただし、レスポンスが非常に悪いうえに、文字が抜ける。ちゃんと動いているわけではない。
posted by すz at 21:28| Comment(0) | TrackBack(0) | USB162

2007年12月03日

テスト用ボードの作成

テスト用にボードを作ってみた。

写真:


回路図:


アイテムラボの変換基板を使用。
USBの D+/D- に付ける抵抗は、データシートには、22Ω(±5%) と書いてあるが、手持ちの関係で 33Ωにしてみた。リセットボタンは省略。HWB ボタンはちゃんと付けた。あと、外部接続用 兼 ISP用 コネクタも作った。

テスト

ISP で使えるかどうか調べるために、USB に接続してみたところ、ホストの Linux 側でなにか動作した。

見てみたら、DFU ブートローダが起動して、USB 機器として認識されていた。



T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 34 Spd=12 MxCh= 0
D: Ver=20.00 Cls=fe(app. ) Sub=01 Prot=00 MxPS=32 #Cfgs= 1
P: Vendor=03eb ProdID=2ffa Rev= 0.00
S: Manufacturer=ATMEL
S: Product=AT90USB162 DFU
S: SerialNumber=1.0.0


ISP を接続して、ヒューズビットを見てみると、データシートの通り、下位バイト 0x5E, 上位バイト 0xD9。内蔵RC オシレータでちゃんとUSB 接続ができているらしい。
訂正:CLKSELは、1110 なので、水晶が選択されている。内蔵RC オシレータは、0010 。
ためしに FLASH 領域をみてみたが、全部 0xff で見えなかった。ロックビットが設定されているらしい。
これは、データシートにも記載されていた。


dfu-programmer を試す


#dfu-programmer at90usb162 get manufacturer
Manufacturer Code: 0x58 (88)

#dfu-programmer at90usb162 get product-name
Product Name: 0x94 (148)

#dfu-programmer at90usb162 get bootloader-version
Bootloader Version: 0x00 (0)

#dfu-programmer at90usb162 frash test1.hex
Validating...
336 bytes used (2.73%)


こんな感じで書き込みできた。test1.hex は無限ループするだけのプログラム。

つぎからは、test1.hex が起動するので、ブートローダは動かない。

さて、いったん USB をはずし、HWB ボタンを押しながら USB に接続すると ブートローダが起動するはず ...

なのだが、なぜか動かない。わからなくなったので、ISP で chip erase してしまった。

次に、Atmel から出ているブートローダを書き込もうとした。... のだが 書き込めない。... フォーマットがなにか変。奇数ではじまっていたりするのはともかく、チェックサムが全部合わないのだ。しょうがないので初期値 0xff として正規化したものを作り書き込んだ。

再度試す。
Bootloader Version が 0 から 1 になっている。
HWB ボタンを押しながら USB に接続してみたところ、ちゃんと接続できた。(4 秒ぐらい かかった。)

もはや元に戻せないのではっきりしたことは分からないが、Version 0 では二度と書き込みできないのかも知れないし、なにかおまじないをすればよかったのかも知れない。それ以前に、私がなにか勘違いしていた可能性もある。

とにかく当面は、ブートローダのみに依存せずに ISP も使えるようにしておいたほうが無難だろう。

後記:
どうも、HWB ボタンを押しながらの USB 接続が、操作的に難しいのが原因らしい。何回か失敗したが、ISP でのリセットを併用したら確実になった。リセットボタンを付ければよいのだが、場所をとるし..スライドスイッチの方が良いかも知れない。

ともあれ、Bootloader での書き込みが問題なくできるようになったので、安心して開発できる。

どうやって開発するか?

Google Code Search で S. Salewski 氏の Free USB firmware for Micro-Controllera というのを発見した。
FIFOCON というキーワードで検索すると avr-libc 以外にはこれしか見つからない。AT90USB1287 用のようだが、唯一公開されているソースかも知れない。

GPL で公開されていて、tar ファイルもあるので、見てみたところ、1 ディレクトリに全部が入っていて avr-gcc でビルドできた。コードも Atmel のよりずっと分かりやすい感じ。また Atmel になかった エンドポイント割り込みの処理が入っている。

まずは、これをみて、処理を考えてみようと思う。

(追記:2010/11/20)



PS3 のおかげで有名になった AT90USB162 だが、DealExtreme という 香港のショップで Designer's Teensy USB Development Board for PS3 : ($16.80/送料無料) として開発ボードが売られるまでになった。



ちなみに Teensy 開発元では、既に扱っていない。が、ブレッドボードの写真に載っていてかつて扱っていたことが判る。


  • Make: 2009/01/28 の記事に載っていた。

    写真を よくみると LED の数が違う。どうも違うもののようだ。
     - DealExtreme の Designer's というのは、コピー品という意味らしい。

  • 他にも Testing the LUFA library on the Teensy とか記事がみつかる。


ちなみに teensy booloader のクライアントソフトは、ここ 。1.0 もサポートしており、command line version だけはソースコードも公開している。
TeensyDuino も 1.0 をサポートはしているのだろう。

  • オリジナルのボードを作ったほうが楽そうなのに、わざわざコピーするのは、このあたりが理由?
  • USB162 を使った 最もコンパクトなボードということで薦めたかったのに微妙な感じになってしまった。

追記 2010/11/23:互換ボードを設計してみた。

詳しくは『Teensy(1.0)互換ボード』の記事参照
posted by すz at 18:31| Comment(56) | TrackBack(0) | USB162

2007年11月30日

CDC クラス調査(1)

AT90USB162メモからの続き

AVR-CDC と Atmel のコードを読み、CDC クラスがどういうものかまとめることにする。( 用語はコードのものをベースにするので、正式なものとは限らない点に注意)

CDC のディスクリプタ

USB デバイスを作る場合、ディスクリプタを作る必要がある。CDC の場合どういうものを作るのかについて

CDC では、大きくわけて次の 7 つのディスクリプタを作らなければならない。


Configuration Descriptor
Interface 0 descriptor (CDC ACM Comm)
CDC Class-Specific descriptor
Endpoint 3 descriptor (Interrupt IN)
Interface 1 descriptor (CDC ACM Data)
Endpoint 1 descriptor (Bulk IN)
Endpoint 2 descriptor (Bulk OUT)


Comm と Data という 2 つのインターフェイスがあって、それぞれに 1つ,2つ 合計 3 つのエンドポイントがある。

次にそれぞれの定義がどうなっているかについて。
Atmel のコードをベースにして、AVR-CDC で違う部分は、[]でコメントを入れる。(ただし記述の順番が違うだけのものは違いとみなさない)

Configuration Descriptor

Size 9
Type 0x02 (Config)
ExternalConfig Size 0x0043
# of Interfaces 2
Index 1 (#1)
StringIndex 0
Attribute 0x80(BUSPOWER)
MAX Power 50 (100mA) [ 100 (200mA)]

Interface 0 descriptor (CDC ACM Comm)

  Size 9
  Type 0x04 (Interface)
Interface Index 0 (#1)
Alternate Setting 0
# of Endpoints 1
Interface Class 0x02 (CDC ACM Comm)
Interface SubClass 2
Interface Protocol 1
Interface String Index 0

CDC Class-Specific descriptor
Atmel の場合 16進数が並んでいるだけ、おまじないと思えばよいかも知れない。4 つのデータが含まれている。意味はわからないが、若干差異がある。

5, 0x24, 0x00, 0x10, 0x01
5, 0x24, 0x01, 0x03, 0x01
4, 0x24, 0x02, 0x06 [ 4, 0x24, 0x02, 0x02 ]
5, 0x24, 0x06, 0x00, 0x01

Endpoint 3 descriptor (Interrupt IN)

  Size 7
  Type 0x05 (Endpoint)
Endpoint Type/Index 080 | 0x3 (IN,#3)
Endpoint Attribute 0x03 (Interrupt)
Max Packet Size 32 [ 8 ]
Interval (ms) 255 [100]

Interface 1 descriptor (CDC ACM Data)

  Size 9
  Type 0x04 (Interface)
Interface Index 1 (#2)
Alternate Setting 0
# of Endpoints 2
Interface Class 0x0a (CDC ACM Data)
Interface SubClass 0
Interface Protocol 0
Interface String Index 0

Endpoint 1 descriptor (Bulk IN)

  Size 7
  Type 0x05 (Endpoint)
Endpoint Type/Index 080 | 0x1 (IN,#1)
Endpoint Attribute 0x02 (Bulk)
Max Packet Size 32 [ 8 ]
Interval (ms) 0

Endpoint 2 descriptor (Bulk OUT)

  Size 7
  Type 0x05 (Endpoint)
Endpoint Type/Index 0 | 0x2 (OUT,#2)
Endpoint Attribute 0x02 (Bulk)
Max Packet Size 32 [ 1 or 6 ]
Interval (ms) 0


このように、ディスクリプタのレベルでは、ほとんど同じになっている。ちなみに、AVR-CDC の Max Packet Size が最大 8 になっているのは、Low-Speed の上限が 8 のため。

そういえば、ベンダーとかデバイスID は?

これは、Configuration ディスクリプタではなく、デバイスディスクリプタに記述するらしい。


  Size 18
  Type 0x01 (Device)
USB Version 0x0200 [ 0x0101 ]
Class 2
SubClass 0
Protocol 0
Max Packet Size 32 [ 8 ]
VENDER_ID 0x03EB [ 0x16c0 ]
PRODUCT_ID 0x2018 [ 0x05e1 ]
RELEASE_NUMBER 0x1000 [ 0x0100 ]
VENDER String Index 0 [1:www.recursion.jp]
PRODUCT String Index 0 [2:USB-232]
Serial# String Index 0
# of CONFIG 1


おおざっぱにいうと、これらディスクリプタを定義して、エンドポイントを 3 つ作り、それぞれに対して、処理を作れば、CDC ドライバになるはず。

(続き)

次に、いったいどんな処理をしなければならないのか?

AVR-CDC が使っている usbdrv ドライバのコードを見てみると、usbProcessRx() という関数がある。これが受信すべての入り口らしい。

まず、usbRxToken が USBPID_SETUP の場合 2つの処理に分けられる。bmRequestType が、USBRQ_TYPE_STANDARD の場合、次のリクエストに対応した処理をしなければならない。


SET_STATUS 0x0
SET_ADDRESS 0x5
GET_DESCRIPTOR 0x6
GET_CONFIGURATION 0x8
SET_CONFIGURATION 0x9
GET_INTERFACE 0xa
CLEAR_FEATURE 0x1
SET_FEATURE 0x3
SET_INTERFACE 0xb

SET_DESCRIPTOR 0x7 (NOP)
SYNCH_FRAME 0xc (NOP)


USBRQ_TYPE_STANDARDでない場合は、usbFuntionSetup() を callしていて、CDC の場合

GET_LINE_CODING 0x20
SET_LINE_CODING 0x21
SET_CONTROL_LINE_STATE 0x22
SEND_BREAK 0x23 (NOP)


の処理があるようだ。

また、usbRxToken & 0x80 の場合、HOST から送信データが来ているので、usbFunctionWriteOut() 関数が呼び出されて、usbcdc.c で受信処理をしている。( データを Buffer に格納するだけ )

ちなみに、HOST への送信はどうしているかというとusbBuildTxBlock() 関数で 送信データを作成しておいて、HOST からリクエストがきたとき送るようにしているらしい。AT90USB162 では、エンドポイントにデータを格納すればよいように思う。

さて、Atmel のコードについて、受信処理を上のキーワードをたよりに探すと、modules/usb/device_chap9/usb_standart_request.c にあることが分かった。

ここらあたりを足がかりにして、AT90USB162 のコードをくみ上げれば良さそう。

見ているコードは、at90usb162-cdc-1_0_1.zip。
ちなみに AT90USB128 用の AUDIO Class のコード at90usb128-demo-audio-1_0_2.zip も同じような構造をしている。メモリとか chip のリソース量の問題がなければ、AT90USB162 でも使えるかも知れない。

ここまでざっと見た感じでは、USBインターフェイスを持っていてもプロトコル処理は 同じようにしなければならない。コードの量は全体で 1000 line 弱で 2KB 程度になりそうだ。

作り方としては、できるだけ usbdrv.c のリプレースになるようにして、usbcdc.c で変更が必要な部分を 切り分けるのが良さそうな気がしている。

これは保留。getc/putc のインターフェイスさえあれば良いので、Atmel のコードで必要なものを集めて、いったんコンパイル可能なものにしてから、書き直すようなことをするかも。


(続き)

Atmel コード解析

エンドポイント設定

No Desc Type IN/OUT size bank timing
#0 Control CONTROL OUT 32 1 SYS_INIT,USB_RESET
#3 Interrupt IN INTERRUPT IN 32 1 SET_CONFIG
#1 Bulk IN BULK IN 32 1 SET_CONFIG
#2 Bulk OUT BULK OUT 32 1 SET_CONFIG

0 番のエンドポイントは、明示的に作らなければならない。そのため、合計4つのエンドポイントを定義している。

バッファに使えるメモリの合計は 176 バイト。そのうち 32x4 = 128 バイト使っていることになる。

バンク数=1 は、いわゆるシングルバッファと同じ。処理中に 受信・送信をオーバラップしてできるように、ダブルバッファの機能があるが、使っていない。


割り込み

割り込みは、USB装置割り込みしか使っていない。どうも、エンドポイントの処理はポーリングのようだ。

データの送受信をしているコードが見当たらないので、はずしているのかも知れない。...が、エンドポイントアクセスのためには、UENUM を設定してアクセスするエンドポイントを選択しなければならないのだが、その部分について割り込み禁止にしていない。..ということは、割り込みでエンドポイントにアクセスしないということになるはず。

割り込みで処理しているのは、RESET の処理のみ。その場で処理するというより、イベントを介して、ポーリングでの処理の中で RESET 処理をしているように見える。
posted by すz at 01:10| Comment(102) | TrackBack(0) | USB162

2007年11月27日

AT90USB162メモ

Atmel から USB インターフェイスが付いた AVR として AT90USB162 が出ている。32 TQFP のパッケージがあってわりと手軽に扱えて、値段も デジキーで520円と安価。

ブートローダが、最初から FLASH に載っているので Windows や Linux から ソフトだけで書き込みできる。水晶は必須で、FT232RL 並とはいえないが、わずかな外付け部品で動かせる。

AVR-CDC のようなドライバさえ充実したら、かなり使い易いものになりそう。

というわけで、こいつで少しばかり遊んでみたいと思っている。

USB のデバイスクラスのうち、CDC とか AUDIO とかを扱えるようになりたいと思っているんだが... デバイスクラスの定義は膨大で正攻法ではなかなか難しそうだ。

最初は、AVR-CDC のコードを移植することから始めれば、一応動かせるものが出来上がるに違いない。で、知識レベルが上がったところで、Atmel のコードを見ながら AUDIO に挑戦するという手順か。

配線メモ

アイテムラボ変換基板ベース


チップ入手先

デジキー520円 (09/10/19 現在 376円)

マイクロファン840円 (09/10/19 現在 577円)

評価基板

OLIMEX AVR-USB-162

サンプルコード・ドキュメント

AVR USB Software Packages


Free USB firmware for Micro-Controller

AT90USB1287用だが参考になる

USB Device Class 定義ドキュメント(www.usb.org)

HERO'S Downloadにある、AVRusb.ZIP に含まれる USB概説(USBspecs.PDF)

MAX3420Eアプリケーションノート(日本語)にある、アプリケーションノート3690 MAX3420EのUSBエニュメレーションコード(およびその他) -- USBの解説がすばらしい。

DFU (Device Firmware Update) ブートローダと対応プログラマ

USB DFU Bootloader Datasheet (pdf) -- データシートのページの下の方

AT90USB162 USB Bootloader v1.0.5 (HEX ファイル) -- Tools & Softwareのページの下の方

dfu-programmer -- Linux で使える DFU 用のプログラマ
    使い方の例
    # dfu-programmer at90usb162 erase 
    # dfu-programmer at90usb162 flash test5.hex


STK526評価キットのページ Hardware User Guide の回路図に、ブートローダを(強制?)起動するボタンがある。OLIMUX AVR-USB-162 も PD7 に ボタンが接続されてて同じ。...データシートにもちゃんと載っていた。キーワードは HWB


WinAVR-20070525 / gcc-4.2.[12] + avr-libc-1.4.7 の問題点

AT90USB162/AT90USB82 が avr5 になっている。avr5 だと AT90USB162/AT90USB82 が持っていない 乗算命令を使ってしまう。

正しくは avr3 にしなければならないが、gcc も avr-libc もバグっている。当面は、乗算を使用しないようにして、乗算命令が出ていないか avr-objdump -d でアセンブラリストを出力し、チェック(mul を grep)する必要がある。

乗算命令が出るようなコードにしてしまったら、コードをなんとか変更する。それでもダメなら 次のオプションでコンパイルしてみると良いかもしれない。


-mmcu=at90usb162

-mmcu=avr3 -D__AVR_AT90USB162__


avr-libc で乗算命令を使うものをリンクしてしまった場合、
まず リンクのオプションを次のように変更する。


-mmcu=at90usb162

-mmcu=avr3 -Tdata=0x800100 -v


これだけでは、だめで、このときの ld のオプションを調べ、avr3/crtm103.o となっているところを avr5/crtusb162.o に変更して、ld を直接実行する。

WinAVR プロジェクトには、このバグについて だいぶ前に報告されている。次のリリースでは修正されると思う。

WinAVR-20070525 の gcc のビルド方法が分かったので、ためしにat90usb162/at90usb82 のアーキクラスを avr3 に変更する avr-gcc.exe を作ってみた。→ usb162-gcckit-0.1.zip

フロントエンドの avr-gcc.exe のみなので、サイズは小さいです (270KB)。もし困っている人がいれば、使ってみてください。


カテゴリ USB162につづく。
posted by すz at 16:21| Comment(2) | TrackBack(0) | USB162