なんとかなるさね

マイコンをネタにブログを始めてみました


RXマイコン基板(RX62N) | USBマルチファンクションファームウェアを作るには? (1) 

以前のエントリで書いた、V850E2/ML4でマスストレージと仮想COMポートを1本のUSBケーブルで同時に使用
可能にするアプリケーションノート/ソースコードを読みながら、RX62N基板で実現するにはどうすれば良いか
調べているのですが、今のところ、読んでみて分かったのは以下のようなところです。

ファームウェア側でやること

(1) USB通信の開始時にFW→PCへ送られるデバイスディスクリプタと呼ばれるデータとコンフィグレーション
  ディスクリプタと呼ばれるデータを、USB機能がマスストレージと仮想COMポートのマルチファンクション
  構成であることを示したものにする。
(2) USB通信のエンドポイント0で行われるコントロール転送という通信チャンネルは、マスストレージと仮想
  COMポートの両方の機能で使用されるので、通信データを各機能に分配する処理が必要になる。
(3) それ以外のエンドポイントの通信データは各機能に従属しているので、普通にUSB通信の送受信処理と通信
  データに基づく各機能の実装を行えば良い。
(4) ルネサスのRX600シリーズ用のUSBアプリケーションノート/ソースコードで使用されているUSBファーム
  ウェアのフレームワークは、マルチファンクションUSBに対応していないので改造が必要になる。

パソコン側でやること

(5) INFファイルを、USB機能がマスストレージと仮想COMポートのマルチファンクション構成であることを
  示したものにする。
(6) マスストレージ機能と仮想COMポート機能のWindowsデバイスドライバは、Windows標準搭載のデバイス
  ドライバが使用出来る。

なお、(2)のコントロール転送の分配処理は、V850E2/ML4用のソースコードでは以下のようになっていました。
(Indexに、実装されている機能の順番の値のようなものが入っているので、それを調べて各機能に分配すれば
良いようです。元のソースでは、usbf850_classreq()でしたが、usbf850_msc_classreq()に書き換えました。)

        if (setup_data.RequstType & C_CLASS_REQUEST) {
            if (setup_data.Index == C_IF0_DSC_bInterfaceNumber) {
                usbf850_msc_classreq(&setup_data); /* Class Request Decode */
            } else if (setup_data.Index == C_IF1_DSC_bInterfaceNumber) {
                usbf850_cdc_classreq(&setup_data); /* Class Request Decode */
            } else {
                usbf850_sendstallEP0(); /* error */
            }
        }
        else {
            usbf850_standardreq(&setup_data); /* Standard Request Decode */
        }


また、(4)のRX600シリーズ用USBファームウェアのフレームワークの改造は、このフレームワークが共通化を
かなり意識したものになっていて複雑な構成のソースコードになっていますので、手に負えなかった場合には、
RX62N Renesas Starter Kitで使用されている単純な構成のソースコードを改造する方が良さそうな気もします。

追記 : メモ

以下のウェブページで公開されていたGRSAKURA_FW_custom.zipに含まれるソースコード(カスタマイズに
必要な数個のソースファイルのみ公開されている)を見ていて気付いたのですが、このUSBファームウェアには、
Renesas MCU Software Libraryのマスストレージファームウェアのソースコードが使用されていそうです。

初期ファームのUSBベンダーID、プロダクトIDを変更できるプロジェクトを公開します
http://japan.renesasrulz.com/gr_user_forum_japanese/m/mediagallery/8.aspx?loc=JP

ファイル: GRSAKURA_FW_custom\usb\resetprg.c (抜粋)

extern unsigned char usb_gpmsc_DeviceDescriptor[];

/////////////////////////////////////////////////////////////////////////////
// Power-on Reset Program
/////////////////////////////////////////////////////////////////////////////
void PowerON_Reset_PC(void)
{
    set_isp(__secend("SI"));    /* Stack address */
    set_usp(__secend("SU"));    /* Stack address */
    set_intb(__sectop("INTERRUPT_VECTOR"));

    /* MCU initialized */
    usbc_cpu_McuInitialize();

    /* Section initialized */
    _INITSCT();
    /* Library initialized */
    /* _INITLIB(); */
    /* Low-level interface initialized */
    /* _INIT_LOWLEVEL(); */
    /* I/O library initialized */
    _INIT_IOLIB();
    /* Other library initialized */
    /* _INIT_OTHERLIB(); */


/* Condition compilation by the difference of the operating system */
    set_psw(0x20000);
    set_psw(0x30000);

    /*  8:idVendor_lo */
    usb_gpmsc_DeviceDescriptor[8] = (USB_VENDORID   & 0xffu);
    /*  9:idVendor_hi */
    usb_gpmsc_DeviceDescriptor[9] = ((USB_VENDORID >> 8)    & 0xffu);
    /* 10:idProduct_lo */
    usb_gpmsc_DeviceDescriptor[10] = (USB_PRODUCTID & 0xffu);
    /* 11:idProduct_hi */
    usb_gpmsc_DeviceDescriptor[11] = ((USB_PRODUCTID >> 8)  & 0xffu),
    usbc_cstd_MainTask(0);

    usbc_cstd_MainTaskStart();
}


きっと、usbc_cstd_MainTask()とusbc_cstd_MainTaskStart()は、マスストレージファームウェアのソース
コードから推測すると、こんな感じなのだと思います。(あくまで大雑把な推測ですが。)

void usbc_cstd_MainTask(USB_VP_INT stacd) //usb_cstd_main_task(USB_VP_INT stacd)
{
    usb_cstd_ScheInit();

    usb_cpu_target_init();

    usb_pmsc_SmpAtapiInitMedia();
}


void usbc_cstd_MainTaskStart( void ) // usb_cstd_task_start( void )
{
    usb_cstd_IdleTaskStart();   /* Idle Task Start */

    usb_pmsc_task_start();      /* Start Peripheral USB driver */

    usb_apl_task_switch();      /* Switch task for nonOS */
}


関連記事

2013/07/19   blog-entry-309   category: RX /* 32bit CISC */

go page top