USBで遊びましょ。

USBで遊んでみようと思って、とりあえずH8とUSBN9602の載ったボードをつくり ました。A/DコンバータとP4ポート(バス)を端子で出しているので、USBデバイス としてちゃんと動作したあかつきには、もう...


肝心のUSBN9602は裏(半田面)だった...水晶の左上の黒い影がそうです。

USBN9602は、1本のアドレス線と8本のデータバスを持っています。勿論、H8から はデータバスを8本引きだすことが可能で、今回もそうしています。また、 USBN9602のA0ピンをH8のA1に、csピンをcs2に接続しました。また、H8はモード5 で動かしていて、USBN960xのアドレスは0x4000000および、0x400002ということ になります。

  1. USBN9602の設定

  2. USBN9602には(USBN9603も同じ)設定のためのレジスタがありますが、その レジスタへの値の書き込みや値の読みとりが一筋縄ではいきません。たい ていのデバイスのレジスタを操作する場合には、直接そのレジスタの値に アスセスすることが可能ですが、USBN960xではまず、A0ピンをHiにしてお いて、(つまり0x400002)に操作したいレジスタの値をデータバスに出しま す。その後A0ピンをLowにした状態で、データバスの値を読む/データバス に値を出すことで、レジスタへの読み書きができます。日本語で書くとよ くわからないかもしれませんが、こういうことです。
         char usbn9602_register_read(char address)
         {
           volatile char* usbn_register;
           char data;
           usbn_register = (char*)0x400002;
           *usbn_register = address;
           usbn_register = (char*)0x400000;
           data = *usbn_register;
           return data;
         }
    	
         void usbn9602_register_write(char address, char data)
         {
           volatile char* usbn_register;
           usbn_register = (char*)0x400002;
           *usbn_register = address;
           usbn_register = (char*)0x400000;
           *usbn_register = data;
         }
         
  3. 割込み処理について

  4. 割込みは、USBN9602からirq信号がくるので、その割りこみを受けたあとMAEVレジスタを読むことで要因が特定できる。こんな感じ
         #define MAEV_INTR       0x80
         #define MAEV_RX_EV      0x40
         #define MAEV_NAK        0x10
         #define MAEV_TX_EV      0x04
         #define MAEV_ALT        0x02
         
         event = usbn9602_register_read(USBN9602_MAEV);        // イベントを調べる
         gprintf(&THIS_MODULE, "\n");
         gprintf(&THIS_MODULE, "usbn9602 interruped 0x%02x.\n", (uint32)event);
         
         if (event & MAEV_RX_EV) {
           usbn9602_rx_event(this);
         }else
         if (event & MAEV_TX_EV) {
           usbn9602_tx_event(this);
         }else
         if (event & MAEV_ALT) {
           usbn9602_alt_event();
         }else
         if (event & MAEV_NAK) {
           usbn9602_nak_event(this);
         }
    
         /*the 9602 produces interrupt LEVELS, the COP looks for edges.  */
         /*So we have to fool the 9602 into producing new edges for us   */
         /*when we are ready to look for them.  We do this by temporarily*/
         /*disabling the interrupts, then re-enabling them.              */
         event=usbn9602_register_read(USBN9602_MAMSK); /*save old mask contents  */
         usbn9602_register_write(USBN9602_MAMSK,(0)); /*disable interrupts */    
         usbn9602_register_write(USBN9602_MAMSK,event); /* re-enable interrupts */ 
    
         return;
         
    最後の部分はH8の割込みをエッジ割りこみで使っているための対処です。こうするとイベントのたびにきちんと割りこみがかかったり解除されたりします。ナショセミから提供されているサンプルを見るまで気づきませんでした。まあH8ならirqをレベル割込みで使うこともできるみたいなので、それでもいいのですが。

  5. ダウンロード
    とりあえず置いてみます。goemonのモジュールなので、適当にサンプル代わりに利用していただければ幸いです。
    ディスクリプタの使い方まわりはCQ出版のUSBの本を参考にしてます。
    usbn9602.c
    usbn9602.h

トップに戻る