訪問者数

ATmega128でプレステコントローラと通信

いやー、長かった。
やっとATmega128でプレステ用コントローラ(以下PS2PADと略す)と通信できました。
使っているPS2PADはロジクールの無線のやつです。

いままでM16Cの時もPS2PADとの通信はIOポートをプログラムで叩いて実現しておりました。
ATmega128への移植時も、そのプログラムをそのまま使う予定だったのですが、少々問題が出てきました。
なぜかATmega128処理速度が遅いのです。
M16Cよりもだいぶ遅いです。

プログラムは馬鹿でかいswitch処理があるのみで、case処理の中は数行のプログラムなのですが、1パルス(一回の割り込み)の処理に14μsほどかかります。理想は2μs程度らしい。

switch処理が遅いのは想像が付くので、最適化してみました。
デフォルトの最適化なしが-O0
最高の最適化が-O3みたいです。

写真の矢印の部分の設定を変えました。
[Project]メニューの[Configration Options]を選ぶと開きます。



-O1にしたところ、14μsから10μsまで早くなりました。
-O3にして見ましたが、おなじく10μs程度でした。
どうやらswitch処理の最適化は-O1でも実施されるようです。

しかし、まだ10μs。目標にはだいぶ遠いです。

なんでこんなに遅いのかを調べるのも面白そうですが、ここはSPIってやつを使ってみることにします。
SPIとはSerial Peripheral Interfaceの略で、PS2PADの通信はSPIが使えるらしいです。
じつはIOポートを叩くプログラムを完成させたころ(2年ほど前かな)にどこかのHPで知りました。もう作ってしまったので、わざわざ作り直すことはしてきませんでしたが、SPIだと、もしかしたら早くなるかもしれません。なぜならATmega128にはSPI機能が付いています。

で、実装してみました。

DDRB = _BV(PINB0) | _BV(PINB1) | _BV(PINB2); // 出力
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR1) | _BV(SPR0) | _BV(DORD) | _BV(CPOL) | _BV(CPHA);
cbi( PORTB, PINB0 ) ; // PAD_SS

wait2(4) ;
SPDR = m_cPadWData[0] ;
loop_until_bit_is_set(SPSR, SPIF);
m_cPadData[0] = SPDR ;
wait2(4) ;

------省略ここから
あと8バイト分くりかえす。
------省略ここまで
sbi( PORTB, PINB0 ) ; // PAD_SS

いままで300行ぐらいあったプログラムが50行程度になりました。
(wait2(4)の行は30μs程度の自前Sleep関数を呼び出しています)
そしてなによりタイマを使用する必要が無いのでタイマが一つ節約できます。

そして速度ですがめちゃ早いです。
上記プログラム例ではFosc/128というもっとも遅い周期を使用しておりますが、十分なほど早いです。


速度は改善されたのですが、まだ通信は出来ませんでした。
原因はPS2PADからの信号の電圧が低すぎて、ATmega128のIOポートではHigh/Lowを認識できないためです。
いろいろなかたのHPをみて調べていると、10k程度のプルアップ抵抗を繋ぐと良いらしい。M16Cの時はそんなことしなくても大丈夫だったので半信半疑だったのですが、手持ちの抵抗をやりくりして10kΩを繋いでみました。

ビンゴ!!

ここまで長かった〜。

さ〜て、アルミ加工アルミ加工。

この記事のトラックバックURL

http://hiderobo.blog26.fc2.com/tb.php/87-82110fe8

コメント

コメントする

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

Template Designed by DW99