評価ボード(QB-R5F10BMG-TB) CAN0の送信割込を使ってCAN通信

お世話になっております。

/*参考 

*

* CAN/LIN/UART/PORT Checker for RL78/F14

* Target: QB-R5F10PPJ-TB (RL78/F14, 100pin, 256KB ROM, 20KB RAM)

* Author: Yasushi Tanaka

/

移植RL78/F13 評価ボード(QB-R5F10BMG-TB)

開発環境: e2-studio7.4

toolChain: Renesas CC-RL C

デバッグツール: e2-Lite

/* CANの割込(vector.c)の設定 */

#pragma interrupt intcan0err_isr(vect=INTCAN0ERR, bank=RB1)

#pragma interrupt intcan0trm_isr(vect=INTCAN0TRM, bank=RB1)

#pragma interrupt intcangrfr_isr(vect=INTCANGRFR, bank=RB1)

#pragma interrupt intcangerr_isr(vect=INTCANGERR, bank=RB1)

現象は、

送信割り込みを使ってCAN送信しようとしますが、

CAN0のスロットにデータは入っても(確認済)、割込のルーチンintcan0trm_isr()は呼び出されません。

下記のように割り込みが許可されていて問題なさそうに見えますが。

/* CAN0送信割り込みを許可 */

MK2H &= (u1)(~RL78F_MK2H_CAN0TRMMK);

考えてられる原因は何でしょうか、ヒントをいただければ助かります。

よろしくお願いします。

(ちなみに割り込み使わずにCAN APIを使って通信は確認できています)

Parents
  • ikkiさん おはようございます、NAKAといいます。

    送信完了の割込みの設定は

    ①送信バッファの割込み許可
    TMIEC |= 0x0001; //CAN0送信バッファ0の割込み許可 
    ②送信割込みのプライオリティ設定
    CAN0TRMPR0 = 0; //CAN送信割込プライオリティ設定
    CAN0TRMPR1 = 1; //01:レベル2
    ③送信割込みマスクフラグ許可
      CAN0TRMMK = 0; //CAN送信割込マスクフラグ 0:許可

    こんな感じで割込み(vect=INTCAN0TRM)に飛んできますよ!

    P.S.
    勘違いだったかもしれませんが、CANの割込みにレジスタバンク使うとなんか調子悪かった覚えがあります。
    しっかり覚えてませんが、無しも試してください。
  • NAKAさま、
    大変お世話になっております。

    送信時のログを取れました。下記は繰り返されます。初めのポート設定はCAN APIでテスト問題ないです。

    しかし、main()の中のcan_init()が何の原因か繰り返し呼び出される、ということは何かリセットはかかっているでしょうか。

    //-----log
    [0000.000.044]--- CAN init PIOR4 = (05)
    [0000.000.136]--- CAN init P1 = (03)
    [0000.000.224]--- CAN init PM1 = (FE)
    [0000.000.312]--- CAN init TMIEC = (000F)
    [0000.000.404]--- CAN init CAN0TRMPR0 = (00)
    [0000.000.496]--- CAN init CAN0TRMPR1 = (01)
    [0000.000.584]--- CAN init CAN0TRMMK = (01)
    [0000.000.684] (can_start) CAN0TRMMK = (00)
    [0000.000.788]CAN:can_count.tx_max=(00)
    [0000.000.916]CA[0001.000.016]CAN:can_count.tx_max=(01)
    [0001.200.012]CAN:can_count.tx_max=(02)
    [0001.400.020]CAN:can_count.tx_max=(03)
    [0001.600.012]CAN:can_count.tx_max=(04)
    [0001.800.020]CAN:can_count.tx_max=(05)
    [0002.000.008]CAN:can_count.tx_max=(06)
    [0002.200.012]CAN:can_count.tx_max=(07)
    [0002.400.020]CAN:can_count.tx_max=(08)
    [0002.600.012]CAN:can_count.tx_max=(09)
    [0002.800.020]CAN:can_count.tx_max=(0A)
    [0003.000.016]CAN:can_count.tx_max=(0B)
    [0003.200.020]CAN:can_count.tx_max=(0C)
    [0003.400.020]CAN:can_count.tx_max=(0D)
    [0003.600.016]CAN:can_count.tx_max=(0E)
    [0003.800.016]CAN:can_count.tx_max=(0F)
    [0004.000.016]CAN:can_count.tx_max=(10)
    [0004.200.016]CAN:can_count.tx_max=(11)
    [0004.400.012]CAN:can_count.tx_max=(12)
    //-----以上のログが繰り返される

    よろしくお願いします。
  • ikkiさん NAKAです。 午前中は出張でした!!

    特別! 出血サービス!

    下のソースをMAIN.cのファイルに張り付けてください。他は一切必要ないです。
    QB-R5F10BMG-TBボードは持ち合わせがないので、北斗電子のF14で作りました。
    なのでポートの設定部分だけをP72,P73からP10,P11にリダクションせずに使ってください。
    送信完了すると割込み関数CAN_TX_INTの中のc_TXがカウントアップしましすし、受信するとc_RXがカウントアップします。

    タイミングもあえてタイマーなど使わずfor文で回してあります。

    もぉ~~ これ以上簡単に出来ない!!!


    /***********************************************************************/
    /* */
    /* FILE :Main.c */
    /* DATE :2019/09/24 */
    /* DESCRIPTION :Main Program */
    /* CPU TYPE :RL78_F14 */
    /* */
    /* NOTE:THIS IS A TYPICAL EXAMPLE. */
    /* */
    /***********************************************************************/
    #include "iodefine.h"

    /************************************************************************/
    /* 割り込みベクタ設定 */
    /************************************************************************/
    void __near CAN_TX_INT(void);
    #pragma interrupt CAN_TX_INT(vect=INTCAN0TRM) //CAN送信割り込み宣言
    void __near CAN_RX_INT(void);
    #pragma interrupt CAN_RX_INT(vect=INTCANGRFR) //CAN受信割り込み宣言

    /************************************************************************/
    /* 関数プロトタイプ宣言 外部関数 */
    /************************************************************************/

    void main(void);

    /************************************************************************/
    /* グローバル変数定義 */
    /************************************************************************/
    unsigned char c_TX;
    unsigned char c_RX;
    unsigned short CAN_SID;
    unsigned short CAN_DLC;
    unsigned char CAN_DATA[8];

    /************************************************************************/
    /************************************************************************/
    /* メインルーチン */
    /************************************************************************/
    /************************************************************************/
    void main(void)
    {
    unsigned long i;

    __DI(); //割り込み 禁止
    //************ オンチップオシレータ32MHzの初期化 **************************/

    CMC = 0x00; //X1発振モード外部クロック入力モードは辞める
    MSTOP = 1; //X1発振回路 停止
    MCM0 = 0; //メインクロックに高速オンチップオシレータを選択
    XTSTOP = 1; //XT1(サブ)発振回路 停止
    SELLOSC = 1; //低速オンチップオシレータ 起動
    CSS = 0; //CPU/周辺をメイン/PLLクロックを選択
    MDIV = 0; //fMP/1=32MHz?
    RTCCL = 0xC2; //RTCのクロック選択 適当?
    TRD_CKSEL = 0; //TRD用クロックの選択 = 32MHz


    /*****************  CANの初期化 **************************/
    //CANポートの設定
    //P72とP73使用時
    PIOR4 = 0x40; //P72.P73をCAN用CTX.CRXに割り当てする 周辺I/Oリダイレクションレジスタ設定 
    P7 |= 0x04; //P72(CTXD)
    PM7 &= 0xFB; //CTXD0(P72pin)を"0":出力に
    PMC7 &= 0xFB; //PMCの設定CAN使用時は"0"
    PM7 |= 0x08; //CRXD0(P73pin)を"1":入力に
    PMC7 &= 0xF7; //PMCの設定CAN使用時は"0"
    //P10とP11使用時
    /*
    P1 |= 0x01; //P10(TXD)34pin
    PM1 &= 0xFE; //CTXD0(P10_34pin)を"0":出力に
    PM1 |= 0x02; //CRXD0(P35pin)を"1":入力に
    */

    //高速オンチップオシレータ32MHz使用
    CAN0EN = 1; //CANモジュールへクロックを供給
    __nop();

    while((GSTS&0x0008)!=0){} //CAN用RAMクリアを待つ GRAMINITフラグが"0":RAMクリアになったか?
    GCTRL &= 0xFFFB; //GSLPR=0 グローバルリセットモードに変遷 (GMDC=01)
    while((GSTS&0x0004)!=0){} //CANグローバルリセットモード変遷を確認
    C0CTRL &= 0xFFFB; //CSLPR=0 チャンネルストップモード⇒チャンネルリセットモードに変遷
    while((C0STSL&0x0004)!=0){} //CANチャンネルリセットモードに変遷を確認

    GCFGL = 0x0000; //DCS=0:fCAN=fCLK/2=16MHzに設定 DLC配置禁止とは?
    C0CFGH = 0x0049; //SJW=1 TSEG2=5 TSEG1=10 に設定 ボーレートプリスケラ(1)分周無しの場合
    C0CFGL = 0x0001; //C0CFGL+1 = 2で分周(16MHz/2 =8MHz)=ボーレートプリスケラ = fCAN_8Mhz/((0+1)×16Tq)= 500Kbps
    //受信ルール設定
    GAFLCFG = 0x0001; //受信ルール数設定 0:ルール無し? or 1:受信バッファを使用する? 
    GRWCR = 0x0000; //受信ルール変更準備
    GAFLIDL0 = 0x0000; //受信ルール① ID設定  比較しない?
    GAFLIDH0 = 0x0000; //受信ルール② 標準ID・データフレーム
    GAFLML0 = 0x0000; //受信ルール③ 対応IDをマスクしない "0000"なので全bitチェックしないので全て受信する。
    GAFLMH0 = 0xE000; //受信ルール④ 標準IDか?とデータフレームか?他のCANノードが送信? を比較する。
    GAFLPL0 = 0x0001; //受信ルール⑤ 受信FIFOバッファ0(GAFLFDP0)をのみ選択する
    GAFLPH0 = 0x0000; //受信ルール⑥ DLCチェックしない
    GRWCR = 0x0001; //受信ルール変更完了
    //受信バッファ設定
    RFCC0 = 0xF302; //RFIGCV(001:1個でFIFO割込)、RFIM(1:1メッセージ受信毎)、RFDC(16)、RFIE(1:受信FIFO割込許可)、
    //送信バッファ設定
    TMIEC = 0x0001; //CAN0送信バッファ0の割込み許可 バッファ1~3は未使用
    C0CTRL |= 0x0008; //RTBO=1:バスオフ強制復帰させる ?
    //割込設定    割り込み名称:INTCANGRFR(グローバルFIFO受信割込み) INTCAN0TRM(チャンネル送信割込み)
    CANGRFRPR0 = 0; //CAN受信割込プライオリティ設定
    CANGRFRPR1 = 1; //01:レベル2
    CANGRFRMK = 0; //CAN受信割込マスクフラグ 0:許可
    CAN0TRMPR0 = 0; //CAN送信割込プライオリティ設定
    CAN0TRMPR1 = 1; //01:レベル2
    CAN0TRMMK = 0; //CAN送信割込マスクフラグ 0:許可

    GCTRL &= 0xFFFC; //GSLPR=0 グローバルリセットモード⇒グローバル動作モードに変遷 (GMDC=00)
    while((GSTS&0x0001)!=0){} //CANグローバル動作モード変遷を確認
    RFCC0 |= 0x0001; //RFE(1:FIFOバッファ使用許可) 注)グローバル動作モードに変更するp1264
    C0CTRL &= 0xFFFC; //CSLPR=0 チャンネルリセットモード⇒CANチャンネル通信モードに変遷 (CHMDC=00)
    while((C0STSL&0x0001)!=0){} ///CANチャンネル通信モードに変遷を確認

    __nop();

    __EI(); //割り込み 許可


    while (1)
    {

    for(i=0;i<0x01FFFFF;i++)
    {
    __nop();
    }

    //CANの定期送信テスト
    TMSTS0 &= 0xF9; //送信結果フラグクリア
    while((TMSTS0 & 0x06)!=0){} //確認

    TMIDH0 = 0x0000; //標準ID データフレーム 履歴をバッファしない
    TMIDL0 = 0x0123; //送信IDバッファ0にIDをSET!
    TMPTR0 = 0x8000; //送信DLCバッファ0にDLCをSET!
    TMDF00L = 0x01; //送信DATAバッファ0にDATAをSET!
    TMDF00H = 0x02; //送信DATAバッファ0にDATAをSET!
    TMDF10L = 0x03; //送信DATAバッファ0にDATAをSET!
    TMDF10H = 0x04; //送信DATAバッファ0にDATAをSET!
    TMDF20L = 0x05; //送信DATAバッファ0にDATAをSET!
    TMDF20H = 0x06; //送信DATAバッファ0にDATAをSET!
    TMDF30L = 0x07; //送信DATAバッファ0にDATAをSET!
    TMDF30H = c_TX; //送信DATAバッファ0にDATAをSET!
    TMC0 |= 0x01; //送信要求 TMTRを"1"に



    }
    }

    /************************************************************************/
    /* CAN送信完了割り込み関数 */
    /************************************************************************/
    void __near CAN_TX_INT(void)
    {
    c_TX++;
    }
    /************************************************************************/
    /* CAN受信完了割り込み関数 */
    /************************************************************************/
    void __near CAN_RX_INT(void)
    {
    __DI(); //割り込み 禁止
    RFSTS0 &= 0xFFF7; //RFIF受信FIFO割り込み要求クリア
    CAN_SID = RFIDL0; //IDを格納
    CAN_DLC = RFPTR0 >> 12; //DLCを格納
    CAN_DATA[0] = RFDF00L; //Data0を格納
    CAN_DATA[1] = RFDF00H; //Data1を格納
    CAN_DATA[2] = RFDF10L; //Data2を格納
    CAN_DATA[3] = RFDF10H; //Data3を格納
    CAN_DATA[4] = RFDF20L; //Data4を格納
    CAN_DATA[5] = RFDF20H; //Data5を格納
    CAN_DATA[6] = RFDF30L; //Data6を格納
    CAN_DATA[7] = RFDF30H; //Data7を格納
    RFPCTR0 = 0x00FF; //バッファポインターインクリメント
    __EI(); //割り込み 許可
    c_RX++;
    }

  • NAKAさま
    ikkiです、いつもお世話になっております。
    本当に至れり尽くせりですね、感謝!感謝!
    完璧に動いています。

    ところで、CANのフォームエラーは送信するデータに何らかのミスがあるという意味でしょうか?
  • NAKAさま、
    ikkiです、いつもお世話になっております。
    送っていただいたCAN割り込みのサンプルですが、
    他のテストやってから戻って再コンパイルして実行したら、CANモニターにエラーで止まってしまいます。
     そこで、新しいプロジェクトを作り、コード生成から同じサンプルを使うとCANエラー出るが、CAN通信は正常に動きます。

    e2 studio, e2 Liteデバッガー
    1)端子割り当て設定(そのまま)
    2)クロック設定(ほとんど変えず)
    3)オンチップデバッグ設定
    4)WDT使用しない設定
    上記のみ実施。

    コード自動生成はソース以外に何か特別処理をされてるでしょうか。
    毎回コード生成からやらないと行けませんか?

    よろしくお願いします。
  • ikkiさん NAKAです。
    ごめんなさい、見逃してました!!

    チョコ先生からアドバイスがあったので、実践しているのですが、NAKAはコード生成は初期設定を参考に覗くだけで、関数は自分で作るようにしています。新規のプロジェクトを作って、MAINに貼るだけで、CAN通信に必要な設定は全てされているため、他は必要ないはずです。僕の北斗電子のF14ボードで一度たりともCANエラーはでたことがないので、多分大丈夫だと思います。

    他の機能を使う時のクロックの設定が違ってたりしないでしょうか?以前マサさんのコードを参考にされてた時はオンチップオシレータの設定を16MHzのようでしたが、上のサンプルではオンチップオシレータ32MHzですけど良かったでしょうか?

  • NAKAさま、
    ご返事ありがとうございます。

    CANの割り込みプログラムは、CANエラーが沢山出て止まっている、って報告したが、いろいろやってる内に、動いているようです。但し、めっちゃ遅くなっています。CANエラーは出ながらも、通信が確認できました、やはり不安定のようです。

    3つのサンプルを切り替えてテストしていますか、
    (1)CAN-API: 割り込み使わないサンプル
    (2)CAN-Int: 作っていただいた割り込みサンプル
    (3)CAN-Drv: ドライバサンプル、割り込み使用

    そして(1)は安定して確認しました。
    (2)は上記の通りです。

    (3)については、いきなりCANエラー割り込み発生して(C0ERFLL=0x2003、0ビットのEWFエラー)全く通信しません。
    このサンプルは4つの送信スロットを使っています。今は原因を追究しています。

    CANのinternal-loop-backテストモードでは正常のようですが、external-loop-backテストモードとnormal-mode通常モードではEWFエラー割り込みが発生します。

    ちなみにバスに接続しているRX65のCAN送信サンプルは安定して通信を確認できていますので、ネットワークは問題ないと見ています。
    何か設定はおかしいに違いありません。
  • ikkiさん NAKAです。
    RL78/F15(CANが2ch)を使って、MAINバスをCAN0chで受信して、そのまま即座に全部ローカルバスへCAN1chから送信する。みたいなことをやってますが、全然遅くないですよ。上記の割込みの設定のままです。ikkiさんのMAINバスの占有率がどれだけギリギリかわかりませんが、車両のCAN程度なら全然大丈夫です。
  • NAKAさま、ありがとうございます。
    改めてテストさせていただきました。

    CAN送信した後に、待ちループを頭から移しまして。
    概ね通信を確認できましたが、
    しかし、CANモニターにエラーがいつも点灯します。
    リトライがしているような感じ、実際の送信は約数百msecから1秒ぐらいの間隔です(CANモニター)。

    試しにC0ERFLLをログに取ってみましたが、0x201Fになっていて、意味が分かりません。
    このレジスタから何のエラーか分かりますか?

    よろしくお願いします。
  • ikkiさん NAKAです。

    確認ですが新規のプロジェクトを作って、以前紹介したサンプルをMAINに張り付けただけの状態(それ以外何もしない)でエラーが起きるのでしょうか?であればハードの可能性もあります。電源が不安定とか、ノイズとか。


    >試しにC0ERFLLをログに取ってみましたが、0x201Fになっていて、意味が分かりません。
    >このレジスタから何のエラーか分かりますか?
    ⇒データシートに記載がありますよ!マイコン(CAN機能)から”H"を送信したのにCANバスでは”L”を検出しちゃったためB1ERRが立って、その状態が続いたのでバスオフになっちゃったって感じでしょうか?

    エラーの原因までは、そのステータスだけでははわかりませんけど(^^)/

    ファイト!
  • NAKAさま、ありがとうございます。

    新しいプロジェクトを作って改めてテストさせていただきました。

    結果は同じです。相変わらずCANエラーが発生しますが、通信もしています。

    カウンターを作ってCANメッセージに入れて確認したら、エラーのせいかカウンターが飛ばされたり、また連続短時間に同じ値のメッセージが表示されたりします。
    ハードウェア的にリトライがかかったりしているようです。

    配線を見直したり、電源を強化したりしましたが、やはり不安定のようなので、ノイズのせいでしょうか?
  • ikkiさん NAKAです。

    CANでトラブった経験がそんなに無いので、アドバイスが難しいかも?ですが終端処理とかしっかりしてますか?

    一応、朝から北斗電子のF14ボード引っ張り出し、プロジェクトにぺたんと貼って動かしてみましたが、やはりエラーは出ませんし、

    データに 「TMDF30H = c_TX;       //送信DATAバッファ0にDATAをSET!」とかしてモニタしても当然、カウンタ値は抜けませんし......

    ハードなのかなぁ~???

    唯一

    極まれにエラーフレームが発生する!という事例で調査したことがあって

    原因と思われるのが、

    基板実装屋さんが電源のコンデンサを指示したものと間違えてESRの高いものが実装されてたことがありました。

    電源ICのカタログでは

    のようにESR3Ω以上だと安定領域から外れる恐れがあり、ついていたアルミ電解は

    のようでさらに温度特性で低温になるとさらに悪化するらしいです。

     

    実際の波形が

    このように負荷電流の変化がトランジェント応答に現れちゃってる感じになったことがあります。

    これでも、CANの規格は十分に満足しており、実機での評価中は2日間一度もエラーフレームは発生しませんでした。

    極低温の環境だと可能性があるのかもしれません。

     

    そして、当初に設計したコンデンサを実装したところ

    このように電源も波形も安定して、その後そういった報告は無いと聞いております。

     

    もう一度確認ですが、先のサンプルに一切手を加えない状態でエラーがあるのでしょうか?

    だとやっぱり、ハード?

Reply
  • ikkiさん NAKAです。

    CANでトラブった経験がそんなに無いので、アドバイスが難しいかも?ですが終端処理とかしっかりしてますか?

    一応、朝から北斗電子のF14ボード引っ張り出し、プロジェクトにぺたんと貼って動かしてみましたが、やはりエラーは出ませんし、

    データに 「TMDF30H = c_TX;       //送信DATAバッファ0にDATAをSET!」とかしてモニタしても当然、カウンタ値は抜けませんし......

    ハードなのかなぁ~???

    唯一

    極まれにエラーフレームが発生する!という事例で調査したことがあって

    原因と思われるのが、

    基板実装屋さんが電源のコンデンサを指示したものと間違えてESRの高いものが実装されてたことがありました。

    電源ICのカタログでは

    のようにESR3Ω以上だと安定領域から外れる恐れがあり、ついていたアルミ電解は

    のようでさらに温度特性で低温になるとさらに悪化するらしいです。

     

    実際の波形が

    このように負荷電流の変化がトランジェント応答に現れちゃってる感じになったことがあります。

    これでも、CANの規格は十分に満足しており、実機での評価中は2日間一度もエラーフレームは発生しませんでした。

    極低温の環境だと可能性があるのかもしれません。

     

    そして、当初に設計したコンデンサを実装したところ

    このように電源も波形も安定して、その後そういった報告は無いと聞いております。

     

    もう一度確認ですが、先のサンプルに一切手を加えない状態でエラーがあるのでしょうか?

    だとやっぱり、ハード?

Children
  • NAKAさま、
    本当にありがとうございます。

    何度も送っていただいたサンプルでトライしてみたが、エラーが必ず出ます。
    しかし、昨日は割と調子が良かったですが、
    今改めて新規のプロジェクトを作ってテストしてみますと、エラーとなって全く通信しません。

    昨日は9割以上通信できていました。
    エラーでパケットが抜けたり、ハードウェア的にリトライしたりしても。

    やはりハードウェア的な問題でしょうか、とにかく不安定です。

    手元に北斗電子の64ピンのRL78/F13ボードがあってまだ動かせていないですが、それでも確かめたいです。

    しっかりターミナルをつけるために、両端にRX65のボード(ターミナル付)を置いています。
    RX65のCANは割り込みを使わないですが、常に安定しています。

    ターゲットボードに付いてるトラシーバーを使わずに他のトラシーバーを使っても、100%通信できているとはできませんでした。
  • NAKAです。

    多分関係ないし、
    解放で大丈夫だと思いますが、TJA1050が実装されているならSpinをGNDに落としておきますか?

    一応
    Control pin S allows two operating modes to be selected:
    high-speed mode or silent mode.
    The high-speed mode is the normal operating mode and is
    selected by connecting pin S to ground. It is the default
    mode if pin S is not connected. However, to ensure EMI
    performance in applications using only the high-speed
    mode, it is recommended that pin S is connected to
    ground.
    と書いてあるので
  • NAKAさま、
    本当にありがとうございます。

    改めてターゲットボードからCTXD0(P10)とCRXD0(P11)を取り、別のトランシーバーにあげたら、送っていただいたサンプルは完璧に動き出しました\(^o^)/
    やはりハードウェアの問題でした。

    感謝感謝!
  • NAKAです。

    >サンプルは完璧に動き出しました\(^o^)/
    ⇒でしょ (^_-)-☆
  • NAKAさま、
    いつもお世話になっております、ikkiです。

    トランシーバーを交換したら、
    同じ現象でしたので、考え変えたら
    原因は電圧が足らなかったことをわかりました!
    3.3Vはトランシーバーを駆動できないみたいです。
    (エミュレータ電源供給は3.3V)5V外部から供給したらパッチリ、サクサク動き出しました。
    これで一安心眠れそうです。
    いろいろありがとうございました。