AVRUSB_Tips

Tips


AVR-GCC(WinAVR)のバージョンはどれが良いの?

  • とりあえず、GCC3ベースの2006-0421というのを使ってます。

USBのD+、D−の配線を下図AVRUSBと同じにしたい

http://www.obdev.at/Images/vusb/circuit-zoomed.gif

  • (1)usbconfig.hを編集します。
    #define USB_CFG_IOPORTNAME      D
    /* This is the port where the USB bus is connected. When you configure it to
    * "PORTB", the registers PORTB, PINB (=PORTB-2) and DDRB (=PORTB-1) will be
    * used.
    */
    #define USB_CFG_DMINUS_BIT      3
    /* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
    * This MUST be bit 0 or 7. All other values will result in a compile error!
    */
    #define USB_CFG_DPLUS_BIT       2
    /* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
    * This may be any bit in the port. Please note that D+ must also be connected
    * to interrupt pin INT0!
    */
    オリジナルはB,0,1ですが、これをD,3,2にします。
  • (2)ポート方向の初期化を変更します。
    int main(void)
    {
    	DDRD = ~(1 << 2);
    	DDRB = ~(USBMASK|(1<<5));    /* all outputs except USB data */
    のDDRDの設定を、以下のように書き換えます。
    	DDRD = ~(3 << 2);   // D2,D3を入力に。他は出力。
    	DDRB = ~(        (1<<5));    //PB5は入力(SPIの'MOSI')
  • 実は(2)の変更に気づかなかったため、HIDaspが動かない動かないとずっと悩んでいたのは秘密。
  • こうすることで、I/Oピン1本と配線1本が節約できますが、
  • HIDaspはじめいくつかのアプリはたいていB,0,1がデフォルトになっています。
  • 何故そうなのかはいまだ不明です。(別の品種ではPORT Dが無いとか???)

コードを縮めたい。(ATtiny2313限定)

  • Cランタイムのスタートアップを自分で書きます。
  • といっても、WinAVRのLIBCソースからcrt1.Sを取り出して改造するだけです。
    https://raw.github.com/iruka-/ATMEL_AVR/master/web/upload/crt_S.zip
  • 自分のソース(main.c)のMakefileにcrt.oを追加する。
    OBJECTS =       usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o
          ↓追加する
    OBJECTS = crt.o usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o
  • リンク時にデフォルトのcrt.oを使わないようにする。
    # file targets:
    main.bin: $(OBJECTS)
    	$(COMPILE) -o main.bin $(OBJECTS)
                                              ↓追加する。
    	$(COMPILE) -o main.bin $(OBJECTS) -nostdlib

注意:

  • .data .bss セクションのサイズが非ゼロであることを前提にしています。
  • どちらかがゼロのときは、.data , .bssそれぞれに対して、コピーループ、クリアループそのものを削除します。

さらに縮めたい。(機種限定なし)

  • AVRUSBのPowerSwitchアプリケーションに含まれているusbdrvは、12MHz版のみでなく、16MHz、16.5MHz版が存在します。
    usbdrv/usbdrvasm12.S
    usbdrv/usbdrvasm16.S
    usbdrv/usbdrvasm165.S
  • これを切り替えるには、main.cディレクトリに置かれている usbconfig.h を編集します。
    /* #define USB_CFG_CLOCK_KHZ       (F_CPU/1000) */
  • これを有効にして、F_CPUを16000000 などとします。
  • どこかでCPUクロック定数=F_CPUを定義していないときは 直接
    #define USB_CFG_CLOCK_KHZ  16000
    としても有効ですが、usbdrv/oddebug.h にF_CPUのデフォルト定義があるので、出来れば oddebug.hをインクルードする前で
    #define F_CPU 16000000
    もしくはMakefile中に-Dオプションで
    -DF_CPU=16000000UL
    としたほうが良いでしょう。
  • PowerSwitch のファームサイズは、クロック別で以下のようになりました。
    ATtiny2313  ROM  RAM
    12MHz            1706      56
    16MHz            1582      56
    16.5MHz         1710      56
    16MHzの時は12MHz時に比べて224バイトも縮んでいます。
    これは美味しいかも。
  • ソースコードのサイズも usbdrv/usbdrvasm16.S が小さいですね。
  • クロック数に余裕があるので、8ビットの処理全部をアンロール展開せずにループ処理で対応出来ているみたいです。

AVRUSBドライバーの16.5MHzモードとは?

  • クリスタルに限らず内蔵RCやセラミック発振の精度を許容する。
  • 12MHz、16MHzはどちらもクリスタル発振の精度が必要です。
  • 16.5MHz±1.0%の精度は必要です。
  • 詳細は-AVRUSBのEasyLoggerアプリケーションにあります。
  • 8ピンのATtiny45などで内蔵RC発振を選択するとピン数が節約出来るので有効。
  • main.cの先頭で、校正済内蔵RCの8MHzをわずかだけオーバークロック調整して8.25MHzにしています。
  • 内蔵RCの後の1/2プリスケーラを通さずに×8PLL(その後1/4されCPUに入る)に入れることでCPUクロックを16.5MHzにしています。(Fuseで設定する HF PLL)
  • 残念ながらATtiny2313では16.5MHzモードを使うことは出来ません。
    • tiny45とはクロックSELの回路が異なっており、x8PLLは存在しないためです。
  • 参考:ATtiny2313で選択できるクロック
    CKSEL3-0意味
    1111-1000外部クリスタル/セラミック発振子
    0110128kHz内部(WDT)発振器
    01008MHz校正付内蔵RC発振器
    00104MHz校正付内蔵RC発振器
    0000外部クロック信号
    0xx1予約

ちなみに8MHz校正付の校正値はOSCCALの値を1〜127まで書き換えることで 約4MHzから12MHz程度まで可変できるようです。(出荷時は8MHzに校正された値になっています)


ところで、どうして16.5MHzなんていう半端なクロックなの?

  • それは、1.5MHzの11倍だから。
  • つまり、LowSpeed USBのベースクロックが1.5MHzなので、1ビットを送受する時間がCPUの命令数で数えてちょうど11ステップになるようにコーディングしてあるわけ。
  • 12MHzの場合はそれが8ステップになるので、超絶技巧プログラミングになるのだけれど、16.5MHzの場合は3ステップの余裕があるから、受信時の同期取りコードを入れることが出来るということらしい。
  • だけど送信時は完全にこっちのペースで送信することしか出来ないので、1%以内の精度は必要らしい。

では、1.5MHzの整数倍になってない16MHzで動くのは何故?

  • そう、16MHzだと、10+(2/3)クロックなんだ。
  • usbdrv/usbdrvasm16.Sのソースを読んでいるが、読解出来ないっす。
  • コメントには凄いことが書いてある。
    • 何をやろうとしているか本当に理解してないならコードに触ってはだめだ。
    • とにかく、これ書いた奴ら、凄すぎ。
    • 全部アセンブラなigorさんも凄いけど、この16を書いた人はもっと尊敬する。というかチャレンジャーだ。
    • usbdrvasm16.S解読

その他のTopic