GR-SAKURAのプロセッサステータスワード(PSW)にある割り込み許可ビットを1にする方法

GR-SAKURAで一定周期ごとにTPUの位相係数モード1を使ってエンコーダの読み取りをしています。
プログラムは、データシートのp1010の位相係数モード応用を見ながら作りました。
https://www.marutsu.co.jp/contents/shop/marutsu/datasheet/R5F563.pdf#search=%27%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B7%E3%83%BC%E3%83%88+RX63N%27
TPU0.TCNTがTPU0.TGRCと一致したときにコンペアマッチが起きてカウンタクリアしています。
その際に立つフラグのクリアを割り込みを使って処理したいのですが出来ません。

 

割り込みの設定はhttps://www.renesas.com/ja-jp/support/training/seminar/web-quick-learning/rx-short-9.htmlの8:40のところまで出来ていると思います。
動画では、8:40から組み込み関数を使ってプロセッサステータスワード(PSW)にある割り込み許可ビットを1にする時に、
#include<machine.h>とsetpsw_i()で出来るといっているのですが#include<machine.h>をかいてコンパイルした時点で
fatal error: machine.h: No such file or directorycompilation terminated.というエラーが起きます。
#include<machine.h>は既存のヘッダファイルなのでかけば使えると思っていました。
machine.hはどうすれば使用できるでしょうか。
また、別の方法でプロセッサステータスワード(PSW)にある割り込み許可ビットを1に出来るのであれば教えて下さい。

開発環境はIDE_for_GR1.02を使っています。
TPU0.TGRCのTIERフラグ,IRフラグ,IENフラグ,が1になっていることはPCのシリアルモニタで確認済みです。
以下にソースコードを記述します。

 
//位相係数モード応用
//コンペアマッチ等のフラグクリアを割り込みで行う

#include "iodefine.h" //IRに簡単にアクセス可能なマクロを提供してくれる


void setup()
{
//ポートの初期化
SYSTEM.PRCR.WORD = 0xA50B;
MSTP(TPU0) = 0;
MSTP(TPU1) = 0;
SYSTEM.PRCR.WORD = 0xA500;

TPUA.TSTR.BIT.CST0 = 0; //TPU0のカウンタ動作停止
TPUA.TSTR.BIT.CST1 = 0; //TPU1のカウンタ動作停止

PORTA.PMR.BYTE = 0x00; //PORTAを初期化 B0WIを設定するため0
PORTC.PMR.BYTE = 0x0C; //PC2(IO8),PC3(IO9)を周辺機器
TPU1.TMDR.BIT.MD = 4; //位相係数モード1
TPUA.TSYR.BYTE = 0x03; //TPU0とTPU1を同期する
//(TPU0.TCNTとTPU1.TCNTの同期クリアが可能になる)

//機能設定
MPC.PWPR.BYTE = 0x40; //PFSWEビット=1 (PFSレジスタへの書き込み許可
//B0WIビット=0 (PFSWEビット書き込み許可)
MPC.PC2PFS.BYTE = 0x03; //TCLKA機能を使用
MPC.PC3PFS.BYTE = 0x03; //TCLKB機能を使用
MPC.PWPR.BYTE = 0x80; //PFSWEビット=0 (PFSレジスタへの書込み禁止)
//B0WIビット=1 (PFSWEビット書き込み禁止)

//ポート方向
PORTC.PDR.BIT.B2 = 0; //TCLKA入力ポート
PORTC.PDR.BIT.B3 = 0; //TCLKB入力ポート

PORTA.PDR.BIT.B0 = 1;
PORTA.PDR.BIT.B1 = 1;

TPU0.TCNT = 0;
TPU0.TCR.BIT.TPSC = 2; // PCLK/16 = 96MHz/16 = 6MHz
//T=1/f[s] = 1/6MHz = 167[ns]
TPU0.TCR.BIT.CCLR = 5; //TGRCレジスタのコンペアマッチでTPU0.TCNTカウンタクリア
TPU1.TCR.BIT.CCLR = 3; //TPU0.TCNTと同期クリア
TPU0.TIORH.BIT.IOA = 0; //TGRAレジスタはアウトプットコンペアレジスタ
//TIOCA0端子 出力禁止
TPU0.TIORL.BIT.IOC = 0; //TGRCレジスタはアウトプットコンペアレジスタ
//TIOCC0端子 出力禁止

TPU0.TGRA = 29940; //速度制御周期 5ms
TPU0.TGRC = 59880; //位置制御周期 10ms
//バッファ動作設定
TPU0.TIORH.BIT.IOB = 12; //キャプチャ入力元はTPU1のカウントクロック
//TPU0.TIORL.BIT.IOD = 0; //アウトプットコンベア機能オンにするが使わない
TPU0.TMDR.BIT.BFB = 1; //TPU0.TGRBとTPU0.TGRDはバッファ動作

//速度周期キャプチャ(TPU1.TGRA)
TPU1.TIOR.BIT.IOA = 12; //TPU0.TGRAのコンペアマッチの発生 インプットキャプチャ要因
//位置周期キャプチャ(TPU1.TGRB)
TPU1.TIOR.BIT.IOB = 12; //TPU0.TGRCのコンペアマッチの発生 インプットキャプチャ要因

TPU0.TIER.BIT.TGIEA = 1; //IRへのTGRA割り込み要求伝達許可
TPU0.TIER.BIT.TGIEB = 1; //IRへのTGRB割り込み要求伝達許可
TPU0.TIER.BIT.TGIEC = 1; //IRへのTGRC割り込み要求伝達許可
TPU0.TIER.BIT.TGIED = 1; //IRへのTGRD割り込み要求伝達許可
TPU1.TIER.BIT.TGIEA = 1; //IRへのTGRA割り込み要求伝達許可
TPU1.TIER.BIT.TGIEB = 1; //IRへのTGRB割り込み要求伝達許可
TPU1.TIER.BIT.TCIEV = 1; //IRへのオーバフロー割り込み要求伝達許可
TPU1.TIER.BIT.TCIEU = 1; //IRへのアンダフロー割り込み要求伝達許可

IPR(TPU0,TGI0C) = 5; //TPU0のTG0C割り込みをレベル5に設定
IEN(TPU0,TGI0C) = 1; //TPU0のTG0C割り込みを許可

PORTA.PODR.BYTE = 0x03; //LED0,LED1は点灯
TPUA.TSTR.BIT.CST0 = 1; //TPU0のカウンタ動作開始
TPUA.TSTR.BIT.CST1 = 1; //TPU1のカウンタ動作開始
Serial.begin(115200);
}

  • わわいです
    >fatal error: machine.h: No such file or directorycompilation terminated.というエラーが起きます。
    このエラーは、machine.h というファイルが見つからない、というエラーです
    machine.h というのは、ツールチェインのルネサス独自の組み込み関数を定義してあるヘッダファイルで、その中にsetpsw_i()も定義してあります。

    おそらく、いまお使いのプロジェクトの設定で、インクルードディレクトリの設定が壊れているものと思われます。

    新規プロジェクトを作成するときに、インクルードディレクトリも含め、いろんな設定がなされますので、一度、別の場所で新たにプロジェクトを作り直し、そこで上記のコードを加えてビルドしてみればどうでしょうか。
  • satosiさん、こんにちは。NoMaYと申します。(Cc: わわいさん)

    IDE for GR1.02ということはGCCですよね?

  • 返信ありがとうございます。調べたところmachine.h自体がなかったので、 ルネサス社の新しい開発環境のCS+をインストールしてそこからmachine.hを使えるように設定して解決しました。ありがとうございました。
  • わわいです
    ああ、GCCだとmachine.hはないですねー。
    GCCだとルネサスが用意している数多のお便利機能が使えないので、初心者の方はCCRXのほうがいいですね。
    #その代わり無料環境ではリンク制限がつきますが。。
  • satoshiです。
    わわいさん返信ありがとうございます。(Cc: NoMaYさん)

    解決したと言ってしまったので大変申し訳ないのですが、CS+ for CC上で同じプログラムをコンパイルするとdelayやシリアル通信の部分を書き直さないといけないことに気がつきました。
    できればIDE for GR1.02のままプログラミングしたいのですが、machine.hを使わずにプロセッサステータスワード(PSW)にある割り込み許可ビットを1にする方法をご存じでないでしょうか。
  • わわいです
    まずはそのGCCに添付の文書を読んで見るテでしょうが、おそらく、GCCではその手の組み込み関数というのは用意してないと思われます。
    ましかし、GCCではインラインアセンブラを使って関数内にアセンブルコードが書けますので、それでそのビットのON/OFF関数を作ることでしょうね。
    まあ、TOPPERSなんかで公開されているソースを漁れば、そこら辺の基本的な関数のソースはすぐ発見できると思うんで、修行半分でそいつのソースを落として読んで行くのもありだと思います

    しかし、CCRXだと、ドキュメント(それも日本語!)が完備してますし、FITモジュールとか自動生成ツールなんかも使えて、サンプルプログラムも豊富にありますんで、今ちょっと無理をしてでもCCRXに移行しといたほうがいいとおもいますねえ。
    最終的に制限を嫌ってGCCに移るにしても、それで修行を積んでおいたほうがいいかと思います
  • satosiさん、こんにちは。NoMaYです。

    調べてみました。IDE for GRですとspecific_instructions.hというヘッダファイルがあり、そこに定義されているsei()が使えそうです。(追記: しまった。あと15分ほど調べるのが遅ければ、わわいさんの投稿と被るような気まずさは無かったのに、、、 あぁ、難しい、、、)

    specific_instructions.h

    specific_instructions.h.txt
    /*
      specific_instructions.h - RX specific functions
      Copyright (c) 2014 Nozomu Fujita.  All right reserved.
    
      This library is free software; you can redistribute it and/or
      modify it under the terms of the GNU Lesser General Public
      License as published by the Free Software Foundation; either
      version 2.1 of the License, or (at your option) any later version.
    
      This library is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Lesser General Public License for more details.
    
      You should have received a copy of the GNU Lesser General Public
      License along with this library; if not, write to the Free Software
      Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    */
    
    #ifndef _SPECIFIC_INSTRUCTIONS_H_
    #define _SPECIFIC_INSTRUCTIONS_H_
    
    #define sei() \
    do { \
      __asm __volatile("setpsw i\n"); \
    } while (0)
    
    #define cli() \
    do { \
      __asm __volatile("clrpsw i\n"); \
    } while (0)
    
    #define isNoInterrupts() \
    ({ \
      bool ret; \
      __asm __volatile( \
        "mvfc psw, %0\n" \
        "btst #16, %0\n" \
        "sceq.l %0\n" \
        : "=r" (ret) \
        : \
        : \
      ); \
      ret; \
    })
    
    #define pushi() \
    { \
      bool _di = isNoInterrupts();
    
    #define popi() \
      if (_di) { \
        cli(); \
      } else { \
        sei(); \
      } \
    }
    
    #define BSET(port, bit) \
    do { \
      volatile byte* _port = (port); \
      int _bit = (bit); \
      __asm __volatile( \
        "bset %1, [%0].b\n" \
        : \
        : "r" (_port), "r" (_bit) \
        : \
      ); \
    } while (0)
    
    #define BCLR(port, bit) \
    do { \
      volatile byte* _port = (port); \
      int _bit = (bit); \
      __asm __volatile( \
        "bclr %1, [%0].b\n" \
        : \
        : "r" (_port), "r" (_bit) \
        : \
      ); \
    } while (0)
    
    #define BTST(port, bit) \
    ({ \
      volatile byte* _port = (port); \
      int _bit = (bit); \
      int ret; \
      __asm __volatile( \
        "btst %2, [%1].b\n" \
        "scnz.l %0\n" \
        : "=r" (ret) \
        : "r" (_port), "r" (_bit) \
        : \
      ); \
      ret; \
    })
    
    #define sbi(port, bit) BSET((port), (bit))
    #define cbi(port, bit) BCLR((port), (bit))
    
    #endif/*_SPECIFIC_INSTRUCTIONS_H_*/
    

  • satoshiです。わわいさん返信ありがとうございます。
    修行を積んでおいて損はないですよね。私はプログラミング経験が浅いので、サンプルプログラムが豊富にあるのは魅力的だと思いました。CCRXへの移行も検討しながら現在の作業を進めていきます。
  • satoshiです。NoMaYさん返信ありがとうございます。
    arduinoにもsei()で割り込み許可をしていたのを思い出しました。specific_instructions.hを使って試してみようと思います。
    気まずくするような質問をしてすみません、、、