AVR-USB(6)

.20 2010 AVR-USB comment(0) trackback(0)
早速12MHzのXtal発振子を買ってきて付け替えました。 その結果このボードでもサンプルプログラムが動きました。めでたしめでたし。

というかこれまで使ってた12.000Mって書いてある発振子は何Hzだったんだろう。一応LEDを点滅させたりする簡単なプログラムは動いてたから発振はしてたはずなんだけど…

[今日のメモ]
brlo等のbranch系の分岐命令で飛べる範囲は-64~+63Wordです。

ジャンプする範囲に2Word命令が入っていたりするとその分飛べる範囲はさらに短くなりますが、 AVRの2Word命令は絶対アドレス指定のjmp, callくらいなので普通は-63命令~+64命令に飛べます。

というわけで普通に次の順番で書くと「brlo命令で飛べる範囲を超えてるよ~」というエラーが出ます。
recv_bit6:(7命令)
recv_bit7:(8命令)
recv_bit0:(7命令)
recv_bit1:(8命令)
recv_bit2:(8命令)
recv_bit3:(8命令)
recv_bit4:(8命令)
recv_bit5:(7命令)

; se0A

recv_stuff6:(6命令)
recv_stuff7:(6命令)
recv_stuff0:(6命令)
recv_stuff1:(6命令)
recv_stuff2:(6命令)
recv_stuff3:(6命令)
recv_stuff4:(6命令)
recv_stuff5:(6命令)

se0:

recv_bit1からse0に飛ぶのに明らかに64命令以上ジャンプすることになるのでエラーがでるわけです。 仕方がないのでrecv_bit5とrecv_stuff6の間にse0Aというラベルを用意し、recv_bit*から飛ぶときは一旦se0Aに飛んで
se0A:
	rjmp	se0

とします。みっともない気がしなくもないですが仕方ないです。
ちなみにrjmpは-2048~+2047命令なので普通に使う分には困ることは滅多にありません。困ったらjmp命令で絶対番地を指定すればいいです。

それから以前syncは64+4clk待てば位相が180°反転して都合がよいと書きましたが、INT0ピンが立ち上がってから割り込みベクタにジャンプするまでに確実に4clkかかっているので64clkの方が安定します。 (以前の記事も修正しないと…)
割り込みベクタにジャンプ:現在位置をスタックに退避(2clk)、cli(=多重割り込み禁止)(1clk)、PC変更(次の命令を読み捨てるので1clk)なので4clk。PC変更とcliは同時にできるかな?そしたら3clkか。

ただし、割り込み要因が発生した場合はその命令を実行してから飛ぶので、2clk命令の実行中ではさらに時間がかかります。



いろいろやった結果今日はめでたくUSB接続時の最初のパケットを受信できました。 ずっとSOFが最初のパケットってだと思ってたんですが本当はSETUPが最初に来るんですね。送られてきたデータはNRZI復号した結果、受信した順に
10110100 00000000 00001000
でした。最初の1011はPIDですが、左がLSbです(USBのプロトコルはLSb firstなので)。 最初これを見てずっと「なんでDATA1(PID=1011)がいきなり送られてくるんだろう…」と悩んでいたのですが勿論DATA1がいきなり送られてくるわけもなくこれはSETUP(PID=1101)パケットでした。

続く0100はPIDを反転したもの。勿論これも左がLSb。

続く7bitの0000000はアドレス。ホストからアドレスが割り振られるまでは0000000として認識されます。

続く4bitはEndPoint。

問題はその次の5bit。CRC-5です。値は例によって左がLSbなので00010。
ここに来てCRCの計算を間違えていたことが分かりました。全bit0なので普通にそれを生成多項式で除算すれば余りは0のような気がします。しかし何度接続してもCRCは00010です。

この辺はもうすこし調べる必要がありそうです。今日は疲れたのでこの辺で…

[次の課題]
1. CRCの計算を直す。
2. かなりの確率で最初のINT0割り込みがSYNCではないという謎の現象が起こっているのでそれに対処する。
関連記事

  • comment
  • secret
  • 管理者にだけ表示を許可する

trackbackURL:http://yuranos.blog11.fc2.com/tb.php/34-17d16a89