FIT USBモジュールをRX631用にコンパイルするとコンパイルエラーになる

RX631でルネサスさんのUSB PCDCサンプル(以下のURLのFIT版を選択する
ことになる)をRX63N用からRX631用にコンフィグレーションを変えてコンパイル
しようとしたところ以下の画面コピーのコンパイルエラーになってしまいました。

https://www.renesas.com/ja-jp/software/D6000454.html
USB Peripheral Communications Devices Class Driver (PCDC) Using Firmware Integration Technology Modules
対象製品名
RX71M
RX64M
RX65N, RX651
RX63N, RX631


エラーメッセージ
r_usb_basic/src/driver/inc/r_usb_extern.h(39):E0520020:Identifier "USB_NUM_USBIP" is undefined
など

対処法を考えているうちにFIT USBモジュールのバグである気がしてきました。

* RX631用の#if~#endifがソース全体に渡って欠落している?

具体的には、以下の流れでソースを追ってみて、そう思うように至りました。

(1) an_r01an2238jj0120_usb\workspace\RX63N\r_config\r_bsp_config.h

/* Group name.
   Character(s) = Value for macro = Description
   30           = 0x0             = RX630 Group
   31           = 0x1             = RX631 Group
   3N           = 0x2             = RX63N Group
   3T           = 0x3             = RX63T Group
*/
#define BSP_CFG_MCU_PART_GROUP          (0x1) // (0x2)

→ BSP_CFG_MCU_PART_GROUP に 0x1 を定義する

(2) an_r01an2238jj0120_usb\workspace\RX63N\r_bsp\mcu\rx63n\mcu_info.h

/* MCU Group name. */
#if   BSP_CFG_MCU_PART_GROUP == 0x0
    #define BSP_MCU_RX630           (1)
#elif BSP_CFG_MCU_PART_GROUP == 0x1
    #define BSP_MCU_RX631           (1)
#elif BSP_CFG_MCU_PART_GROUP == 0x2
    #define BSP_MCU_RX63N           (1)
#elif BSP_CFG_MCU_PART_GROUP == 0x3     
    #define BSP_MCU_RX63T           (1)
#else
    #error "ERROR - BSP_CFG_MCU_PART_GROUP - Unknown MCU Group chosen in r_bsp_config.h"
#endif

→ 上の項番(1)により BSP_MCU_RX631 が定義される

(3) an_r01an2238jj0120_usb\workspace\RX63N\r_usb_basic\src\driver\inc\r_usb_basic_define.h

/* The number of USBIP */
#if defined(BSP_MCU_RX64M) || defined(BSP_MCU_RX71M) || defined(BSP_MCU_RX63N)
    #define USB_NUM_USBIP           (2u)
#endif /* defined(BSP_MCU_RX65N) */

#if defined(BSP_MCU_RX65N)
    #define USB_NUM_USBIP           (1u)
#endif /* defined(BSP_MCU_RX65N) */

→ ところが BSP_MCU_RX631 の場合の#if~#endifが無い

(4) an_r01an2238jj0120_usb\workspace\RX63N\r_usb_basic\src\driver\inc\r_usb_extern.h

extern uint16_t g_usb_change_device_state[USB_NUM_USBIP];

→ ここで E0520020:Identifier "USB_NUM_USBIP" is undefined のコンパイルエラーになる
→ → 上の項番(3)で BSP_MCU_RX631 の場合の#if~#endifが無いので当然そうなる
→ → → ソース全体をgrepしても、そういう#if~#endifが全く無い
→ → → → それってバグなのでは?

なお、以下の2つのファイルの設定も変更しています。

(A-1) an_r01an2238jj0120_usb\workspace\RX63N\demo_src\inc\r_usb_pcdc_apl_config.h
(A-2) an_r01an2238jj0120_usb\workspace\RX63N\r_config\r_usb_basic_config.h

/** [USB module selection setting]
 *  USB_CFG_IP0         : Uses USB0 module
 *  USB_CFG_IP1         : Uses USB1 module
 */
#define USB_CFG_USE_USBIP           (USB_CFG_IP0) // (USB_CFG_IP1)

また、以下に手を入れていますがPLLクロック発振安定待機時間をGR-CITRUSに
合わせる(GR-CITRUSのUSBMSCファームウェアの設定に合わせる)変更です。

(B) an_r01an2238jj0120_usb\workspace\RX63N\r_bsp\board\rskrx63n\resetprg.c

  • がじぇっとるねさすコミュニティに投稿したブログから参照することにしましたので
    本文を少し変更しました。また、その為に、以下のソース変更内容を追記しました。

    (B) an_r01an2238jj0120_usb\workspace\RX63N\r_bsp\board\rskrx63n\resetprg.c

    このファイルに対しては以下の赤字箇所を追加しています。

    #if (BSP_CFG_CLOCK_SOURCE == 4)
        /* PLL is chosen. Start it operating. Must start main clock as well since PLL uses it. */
        /* Wait 65,536 cycles * 12 MHz = 5.46 ms */
        SYSTEM.MOSCWTCR.BYTE = 0x0C;        

        /* Set the main clock to operating. */
        SYSTEM.MOSCCR.BYTE = 0x00;          

      #if 1 // for GR-CITRUS
        /* Following value is obtained from HardwareSetup() of Web Compiler's sketch template. */
        /* PLL wait is 2,097,152 cycles * 192 MHz (12 MHz * 16) = 10.92 ms*/
        SYSTEM.PLLWTCR.BYTE = 0x0E;         
      #else
        /* PLL wait is 1,048,576 cycles * 192 MHz (12 MHz * 16) = 5.46 ms*/
        SYSTEM.PLLWTCR.BYTE = 0x0D;         
      #endif

        /* Set PLL Input Divisor. */
        SYSTEM.PLLCR.BIT.PLIDIV = BSP_CFG_PLL_DIV >> 1;

        /* Set PLL Multiplier. */
        SYSTEM.PLLCR.BIT.STC = BSP_CFG_PLL_MUL - 1;

        /* Set the PLL to operating. */
        SYSTEM.PLLCR2.BYTE = 0x00;          

        /* The delay period needed is to make sure that the main clock and PLL have stabilized. This delay period is
           tPLLWT2 when the main clock has not been previously stabilized. According to the Renesas Technical Update
           document TN-RX*-A021A/E this delay is defined as:
           n = Wait time selected by PLLWTCR.PSTS[] bits
           tMAINOSC = Main clock oscillator start-up time. From referring to various vendors, a start-up time of 4ms appears
                      to be a common maximum. To be safe we will use 5ms.
           tPLLWT2 = tMAINOSC + tPLL1 + ((n + 131072)/fPLL)
           */
      #if 1 /* for GR-CITRUS */
           /*
           tPLLWT2 = 5ms + 500us + ((2097152 + 131072)/192MHz)
           tPLLWT2 = 17.10ms
           A delay of 18ms has been used below to account for variations in the LOCO.
           18ms / 86us (per iteration) = 210 iterations */
        for(i = 0; i < 210; i++)             
        {
            /* Wait 18ms. See comment above for why. */
            nop() ;
        }
      #else
           /*
           tPLLWT2 = 5ms + 500us + ((1048576 + 131072)/192MHz)
           tPLLWT2 = 11.64ms
           A delay of 12ms has been used below to account for variations in the LOCO.
           12ms / 86us (per iteration) = 140 iterations */
        for(i = 0; i < 140; i++)             
        {
            /* Wait 12ms. See comment above for why. */
            nop() ;
        }
      #endif
    #else
        /* Set the PLL to stopped. */
        SYSTEM.PLLCR2.BYTE = 0x01;          
    #endif

    回避策としては、RX631用にコンパイルするのではなくRX63N用として以下の赤字
    箇所のようにしてコンパイルすればコンパイル出来ますし、そのようにビルドしても
    今回のサンプルプログラムはGR-CITRUSで動作しました。

    (I) an_r01an2238jj0120_usb\workspace\RX63N\r_config\r_bsp_config.h

    /* Package type. Set the macro definition based on values below:
       Character(s) = Value for macro = Package Type/Number of Pins/Pin Pitch
       FC           = 0x0             = LQFP/176/0.50
       BG           = 0x1             = LFBGA/176/0.80
       LC           = 0x2             = TFLGA/177/0.50
       FB           = 0x3             = LQFP/144/0.50
       LK           = 0x4             = TFLGA/145/0.50
       FP           = 0x5             = LQFP/100/0.50
       LA           = 0x6             = TFLGA/100/0.50
       FN           = 0x7             = LQFP/80/0.50
       FM           = 0x8             = LQFP/64/0.50
       FL           = 0x9             = LQFP/48/0.50
    */
    #define BSP_CFG_MCU_PART_PACKAGE        (0x5) // (0x0)



    /* ROM, RAM, and Data Flash Capacity.
       Character(s) = Value for macro = ROM Size/Ram Size/Data Flash Size
       E            = 0xE             = 2MB/128KB/32KB
       D            = 0xD             = 1.5MB/128KB/32KB
       B            = 0xB             = 1MB/128KB/32KB
       A            = 0xA             = 768KB/128KB/32KB
       8            = 0x8             = 512KB/64KB/32KB
       7            = 0x7             = 384KB/64KB/32KB
       6            = 0x6             = 64KB/8KB/8KB
       5            = 0x5             = 48KB/8KB/8KB
       4            = 0x4             = 32KB/8KB/8KB
       0            = 0x0             = 0/128KB/0
    */
    #define BSP_CFG_MCU_PART_MEMORY_SIZE    (0xE) // (0xF) // (0xB)

    /* Group name.
       Character(s) = Value for macro = Description
       30           = 0x0             = RX630 Group
       31           = 0x1             = RX631 Group
       3N           = 0x2             = RX63N Group
       3T           = 0x3             = RX63T Group
    */
    #define BSP_CFG_MCU_PART_GROUP          (0x2) // (0x1) // (0x2)

    以下は動作を確認した時の画面コピーです。(ちなみに、コマンドプロンプト
    (あるいはWindowsのスタートメニューの[プログラムとファイルの検索]入力)で
    devmgmt.mscと入力するとデバイスマネージャを直に開くことが出来ます。)








    なお、今回のサンプルプログラムですが、e2 studio用プロジェクトファイルを
    CS+で開く時にプロジェクト名を変更するとインクルードパスが合わなくなって
    コンパイルエラーになってしまったので、CS+上でインクルードファイルパスを
    修正しています。

    プロジェクトファイルを開く時にプロジェクト名を指定出来るものの、、、



    コンパイルエラーになるのでインクルードパスの修正が必要(元々存在しないr_dmaca_rxフォルダに関しては保留)
    修正前:

    修正後:

  • 2017/05/23 23:58

    使用したモジュールがバージョンアップされていて、以下のURLとファイル名に変わっていました。
    (すみません、まだダウンロードしていませんので投稿内容と変わっているかも知れません。)

    USB Peripheral Communications Devices Class Driver (PCDC) Using Firmware Integration Technology Modules
    https://www.renesas.com/ja-jp/software/D6000997.html
    an_r01an2238jj0121_usb.zip

    ルネサスサンプルコード検索で検索する場合

    an_r01an2238
    https://www.renesas.com/ja-jp/search/keyword-search.html#genre=sampleprogram&q=an_r01an2238


    2017/05/25 06:46

    ダウンロードして、バージョンアップされたモジュールのソースを確認したところ、DMA転送を使用する
    場合のUSBドライバの処理が変更されていました。ソースには以下の変更履歴が追加されていました。

    26.01.2017 1.21 Support DMAC Technical Update for RX71M/RX64M USBA.

  • NoMaYさん

    シェルティです、こんにちは。

    本件ですがRXマイコンのデバイスドライバを作っているメンバーに聞いてみました。
    このスレッドの指摘のおかげでRX631の抜けに気が付いたそうで、次の版(10月位)で直すと仰っていました。
    本当に貴重なフィードバックをいただきまして、参考になります。
    他にも変な挙動を見つけたら報告いただけましたら、
    (おもにRXマイコン関連だけですが)私が可能な限りメッセンジャーします。

    e2 studioのプロジェクトをCS+のプロジェクトにコンバートすると
    インクルードパス(ライブラリのパスも)が変になるのは私も引っかかりました。
    過去ツール開発のメンバーに聞いてはみたのですが、こちらは少し直る見込みが薄いかもしれません。
    私もいつも手作業でパス修正しています。

    以上です
  • これまでの投稿では、GR-CITRUSに関して変更の必要が無かったので言及していなかった
    のですが、FIT USBモジュールのコンフィグレーションという点では、GR-CITRUS以外
    (かつRDKRX63NでもRSKRX63Nでも無い)ボードでは、以下の関数で行われているレジスタ設定を
    ボードのUSB周りの構成に合わせて変更する(更には追加する?)必要があるかも知れません。
    (基本的には#defineでモジュールの設定を切り替えるようになっているのですが、ここだけ
    必要に応じてソースを直接変更する必要があるかも知れないと思いました。)

    ファイル: an_r01an2238jj0120_usb\workspace\RX63N\demo_src\r_usb_pcdc_echo_apl.c
    ファイル: an_r01an2238jj0120_usb\workspace\RX63N\demo_src\r_usb_pcdc_uart_apl.c
    ファイル: an_r01an2238jj0121_usb\workspace\RX63N\demo_src\r_usb_pcdc_echo_apl.c
    ファイル: an_r01an2238jj0121_usb\workspace\RX63N\demo_src\r_usb_pcdc_uart_apl.c
    関数: static void usb_pin_setting (void)
    内容:

    static void usb_pin_setting (void)
    {
        R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_LPC_CGC_SWR);
        R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_MPC);

    #if USE_USBIP == USE_USBIP0
        PORT1.PMR.BIT.B4    = 0u;
        PORT1.PMR.BIT.B6    = 0u;
        MPC.P14PFS.BYTE     = 0x11; /* USB0_DPUPE */
        MPC.P16PFS.BYTE     = 0x11; /* USB0_VBUS */
        MPC.PFUSB0.BIT.PUPHZS   = 1u;
        PORT1.PMR.BIT.B4    = 1u;
        PORT1.PMR.BIT.B6    = 1u;

    #else   /* USE_USBIP == USE_USBIP0 */
        PORT1.PMR.BIT.B5        = 0u;
        PORT1.PMR.BIT.B7        = 0u;
        MPC.P15PFS.BYTE         = 0x11; /* USB1_DPUPE */
        MPC.P17PFS.BYTE         = 0x11; /* USB1_VBUS */
        MPC.PFUSB1.BIT.PUPHZS   = 1u;
        PORT1.PMR.BIT.B5        = 1u;
        PORT1.PMR.BIT.B7        = 1u;

    #endif  /* USE_USBIP == USE_USBIP0 */

        R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_MPC);
        R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_LPC_CGC_SWR);
    }/* End of function usb_pin_setting */

    関係しそうなハードウェアマニュアルの一例

    resource.renesas.com/resource/lib/jpn/online_docs/um/RX/RX63N_RX631_ja/?MPC_63N#TOC_22_2_27


    resource.renesas.com/resource/lib/jpn/online_docs/um/RX/RX63N_RX631_ja/?MPC_63N#TOC_22_2_28


    [追記]

    RDKRX63N回路図
    (PDFそのものへのリンクが見当たらなかったので省略)

    RSKRX63N回路図
    www.renesas.com/ja-jp/doc/products/tool/doc/001/r20ut0437eg0300-rskrx63n-256k-schematics.pdf

    GR-SAKURA回路図
    sakuraboard.net/gr_sakura_schematic_color.pdf

    GR-CITRUS回路図
    github.com/wakayamarb/wrbb-schematic/blob/master/GR-CITRUS/CITRUS1.0.pdf

  • NoMaYさん

    こんにちは、シェルティです。

    いつも貴重な情報をありがとうございます。
    仰る通り端子設定はボード毎に変更する必要がありますね。

    RXマイコン用のFITモジュールの構成についておさらいしてみます。
    www.renesas.com/.../about-fit.html

    上記URLの一番上の絵で、「FITモジュール」と書いてあるブロックは、
    サンプルソフト上はフォルダ名「r_xxxx_rx」という名称のフォルダにまとまっています。
    SCIなら、r_sci_rx、Etherならr_ether_rx 、FLASHならr_flash_rxですね。
    このフォルダはユーザが変更しなくて済むようにモジュール化および評価がなされていて、
    かつ、ボード依存のコードはなく、CPU依存のコードは#ifdefまたは各モジュール内の
    targetsフォルダでCPU毎に切り分けられています。
    r_flash_rx が膨大な全RXマイコンラインナップのROM容量、フラッシュの種別を
    うまく#ifdefで切り分けている様はなかなかに壮観です。
    r_flash_rxはtargetsフォルダにCPU毎の全ROM容量ラインナップを包含したコードがあり、
    r_config/r_bsp_config.hのCPU型名設定を読み込んで、どのROM容量かを決定している、
    という構造です。他のFITモジュールも似たような仕組みでCPUの差を吸収していますね。

    一方で、RXマイコンは1端子に複数機能が割り当てる機構があり、
    どの機能をどの端子に割り当てるかはMPC(マルチファンクションピンコントローラ)の
    レジスタで設定する必要があります。これは、ユーザボードの設計次第ですので、
    FITモジュール側ではあらかじめコードを用意しておくことができません。
    ルネサススタータキットのボードの場合は、サンプルコード上でこの設定ができた状態で
    配布されているのでそのまま動くのですが、NoMaYさんの情報通り、
    それ以外のボードの場合は、ユーザがMPCの設定コードをボードに合わせて書く必要があります。
    #逆にいえば、MPCの設定さえ気を付ければ、FITモジュール部分「r_xxxx_rx」は
    基本的に無改造で使えます。

    最新のRXマイコン(RX65N/RX651)ですと、コード生成とFITの融合が図られ始めているようで、
    スマートコンフィグレータなるもので、端子設定まで含めてツール側でじょうずに調整するようです。
    www.renesas.com/.../smart-utility.html
    #実際に試してみると、現時点ではまだちょっと色々難がある模様です。

    このあたりが改善されてくると、ユーザボードの場合でも以下手順で
    あまり気にせずソフトウェアのインテグレートができるようになってくるのでは、
    と考えています。

    ①GUIで端子設定をほどこす
    ②単純な機能はコード生成がカバーしているようなので、コード生成でコード出力
    ③複雑な機能(USBやEtherやFlash)はFITモジュールがカバーしているようなので、FITモジュールをインポートしてコード出力
    ④ビルド

    以上です
  • シェルティさん、こんにちは。NoMaYです。

    情報有難うございました。RXの一部の品種ではスマートコンフィグレータが既にe2 studioで
    使用可能なのですね。(e2 studioでは、RZ/A1にもスマートコンフィグレータというGUIツールが
    あり、混同してしまって気付きませんでした。)

    それはそれとして、目が覚めた後、唐突にあれっと思ったのですが、usb_pin_setting()関数が
    ユーザアプリケーション側のソースに記述されているのは、FITの目論見の1つであるユーザ
    アプリケーション側とボードサポートパッケージ側の2つに分けた構造にしてマイコン間(というか
    この場合はボード間になってしまいますが)の移行を容易にしようとしていることと、ちょっと
    チグハグになっているような気がしてきました、、、

  • NoMaYさん

    こんにちは、シェルティです。

    そうですね、FITの枠組みは現状完成形とまではいかず、もう一息、という感じのところが見受けられますね。
    端子設定は最たる例のような気がします。
    FITモジュール(例えば r_sci_rx)の内部に端子設定コードを埋め込むと、ユーザボードの場合に、
    r_sci_rx内部のコードをユーザが改造しなければならないので、端子設定コードはFITモジュール外部に
    存在するケースが多いのだと思います。
    スマートコンフィグレータの機能をみると、端子設定はツール側で対応する方針に進みつつあるように感じます。

    以上です