はじめまして。Tayaと申します。RX651で、UART(SCI5)にDMA(送信:DMA4、受信:DMA5)を使っています受信側は問題なく動きましたが、送信側が2点の問題があり、何か設定ミスをしていると思われます。問題1:自走生成される「r_sci_rx65n.c」に2か所のパッチが必要。問題2:送信割込み(sci5_txi5_isr)が動作してしまう。ただ、割込み回数は送信データ数より少ない。修正箇所や、調査箇所があったら、教えていただきますように、お願いいたします。
SCI設定には、r_sci_rxを使っています。デフォルトからの変更内容は以下です。・SCI5のソフトサポートを有効にする。・SCI5の送信にDMAを使用する・SCI5の受信にDMAを使用する・SCI5の送信にはDMA4を使用する・SCI5の受信にはDMA5を使用する・送受信の端子設定を有効にする。DMAには、送信にConfig_DMAC4と、受信にConfig_DMAC5を使用しました。受信側は問題なく動作しているので省略します。Config_DMAC4の設定は以下です。・起動要因はSCI5(TX5)・起動要フラグをクリアする・転送モードノーマルモード・転送元アドレスに拡張リピートエリアを設定し、転送元アドレスは内蔵拡張RAMのアドレス(4Kアライン)・転送先アドレスは、0x0008A0A3(SCI5のTDR)このままでは、送信側のDMAが使用できなかったので、「r_sci_rx65n.c(27.12.2022 4.60版)」に次のパッチを入れました。・sci_initialize_ints関数の463行目が「ENABLE_RXI_INT;」ですが、その下に「ENABLE_TXI_INT;」を入れました。・sci5_txi5_isr割込み内の、「txi_handler(&ch5_ctrl);」の処理をコメントアウトしました。受信側では、正常に動作し、受信割込みは発生していません。
よろしくお願いいたします。
わわいです
コード生成は使ったことないですし、RXのSCIでDMAを使ったことはありません。が、
ルネサスのSCIでは伝統的に、DMAのトリガは割り込みを使います
そのうえで、割り込みを生成しないようにするには、該当する割り込みの優先度をゼロ、として割り込みを抑制します
現状で割り込みがかからない、あるいは割り込みが歯抜けになる、というのは、CPUが割りこみを認識する前にDMAによる処理が間に合うかどうか、ということかと思います
かわいさん
ありがとうございます。
送信側の割り込み優先度をゼロにして試したところ、送信側DMAが動かなくなりました。MCUの内部で、この設定以降に割込み要求とDMA要求が分岐しているということでしょうか。
DMAを同じように設定しているのに、受信では割込みが入らず、送信では割込みが入る事象について、かわいさんのご説明で納得がいきました。受信DMAはDMA要求後、直ぐにSCIのRDRを読みに行くと思われますが、送信DMAではDMA要求後、メモリを読出し、その後にTDRに下記に行くので、時間がかかり、割込みが入ってしまう、と解釈しました。
ありがとうございました。
SCIとDMACの動作を見てみました。
(スマートコンフィグレータでSCIとDMACをコンポーネント追加した簡単なコードです)
(SCIはSCI1を使いました)
・DMACの設定
・実行したプログラム
/********************************************************************************************************************** * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No * other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all * applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM * EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES * SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO * THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of * this software. By using this software, you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * * Copyright (C) 2020 Renesas Electronics Corporation. All rights reserved. *********************************************************************************************************************/ /***********************************************************************/ /* */ /* FILE :Main.c or Main.cpp */ /* DATE :Tue, Oct 31, 2006 */ /* DESCRIPTION :Main Program */ /* CPU TYPE : */ /* */ /* NOTE:THIS IS A TYPICAL EXAMPLE. */ /* */ /***********************************************************************/ //#include "typedefine.h" #include "r_smc_entry.h" #pragma address g_sci_tx_buf=0x00800000 #pragma address g_sci_rx_buf=0x00801000 unsigned char g_sci_tx_buf[0x1000]; unsigned char g_sci_rx_buf[0x1000]; volatile unsigned long g_sci_txi_count = 0; //TXI割り込みの回数をカウント volatile unsigned long g_sci_tei_count = 0; //TEI割り込みの回数をカウント volatile unsigned long g_sci_rxi_count = 0; //RXI割り込みの回数をカウント void sci_tx_buf_copy(unsigned char *buf); #ifdef __cplusplus //#include <ios> // Remove the comment when you use ios //_SINT ios_base::Init::init_cnt; // Remove the comment when you use ios #endif void main(void); #ifdef __cplusplus extern "C" { void abort(void); } #endif void main(void) { unsigned long i; unsigned char dummy1, dummy2; //メモリ初期化 for (i=0; i<0x1000; i++) { g_sci_tx_buf[i] = 0x00; g_sci_rx_buf[i] = 0x00; } R_Config_SCI1_Start(); R_Config_DMAC4_Start(); R_Config_DMAC5_Start(); //受信側 DMAC5.DMCRA = 10; //受信10バイト R_Config_SCI1_Serial_Receive(&dummy1, 1); //RE=RIE1に設定 //送信側 sci_tx_buf_copy("SCI DMAC test\r\n"); //0x0080_0000~にコピー(15バイト) DMAC4.DMCRA = 15; //送信15バイト R_Config_SCI1_Serial_Send(&dummy2, 1); //DMAC起動トリガ while(1) { __nop(); } } #ifdef __cplusplus void abort(void) { } #endif void sci_tx_buf_copy(unsigned char *buf) { unsigned long index = 0; while (*buf != '\0') { g_sci_tx_buf[index++] = *buf++; } }
・メモリ(TX送信バッファ)
上記のメッセージをDMACを使用して出力させる作戦です。
・端末への出力
期待通りに出力されました。
・出力後の割り込みの回数
TXI割り込みが1回入っています。これは、15バイト転送後、DMACが停止した後にTDRが空になったタイミングで生じているモノなので妥当だと思います。(DMACが動いている時にはTXI割り込みは生じていません)
なお、割り込み優先度をゼロに設定
IPR(SCI1, RXI1) = 0; IPR(SCI1, TXI1) = 0;
しても、DMAC(端末への文字出力&文字入力)は、問題なく動いていました。(かつ、割り込みは発生しません)
私が試行した限りにおいては、
→DMACがちゃんと動いている限りでは、割り込みが掛かることは無い様に見受けられます
→割り込み優先度0に設定してもDMACは起動されました
という動作です。
・参考(割り込み回数のカウント)
/*********************************************************************************************************************** * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all * applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT, * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability * of this software. By using this software, you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved. ***********************************************************************************************************************/ /*********************************************************************************************************************** * File Name : Config_SCI1_user.c * Component Version: 1.12.0 * Device(s) : R5F5651EDxFP * Description : This file implements device driver for Config_SCI1. ***********************************************************************************************************************/ /*********************************************************************************************************************** * Function Name: r_Config_SCI1_transmit_interrupt * Description : This function is TXI1 interrupt service routine * Arguments : None * Return Value : None ***********************************************************************************************************************/ #if FAST_INTERRUPT_VECTOR == VECT_SCI1_TXI1 #pragma interrupt r_Config_SCI1_transmit_interrupt(vect=VECT(SCI1,TXI1),fint) #else #pragma interrupt r_Config_SCI1_transmit_interrupt(vect=VECT(SCI1,TXI1)) #endif static void r_Config_SCI1_transmit_interrupt(void) { extern volatile unsigned long g_sci_txi_count; g_sci_txi_count++; r_Config_SCI1_callback_transmitend(); } /*********************************************************************************************************************** * Function Name: r_Config_SCI1_transmitend_interrupt * Description : This function is TEI1 interrupt service routine * Arguments : None * Return Value : None ***********************************************************************************************************************/ void r_Config_SCI1_transmitend_interrupt(void) { extern volatile unsigned long g_sci_tei_count; g_sci_tei_count++; r_Config_SCI1_callback_transmitend(); } /*********************************************************************************************************************** * Function Name: r_Config_SCI1_receive_interrupt * Description : This function is RXI1 interrupt service routine * Arguments : None * Return Value : None ***********************************************************************************************************************/ #if FAST_INTERRUPT_VECTOR == VECT_SCI1_RXI1 #pragma interrupt r_Config_SCI1_receive_interrupt(vect=VECT(SCI1,RXI1),fint) #else #pragma interrupt r_Config_SCI1_receive_interrupt(vect=VECT(SCI1,RXI1)) #endif static void r_Config_SCI1_receive_interrupt(void) { extern volatile unsigned long g_sci_rxi_count; g_sci_rxi_count++; r_Config_SCI1_callback_receiveend(); }
r_Config_SCI1_transmit_interrupt(void) 関数に飛んできた回数をカウントしています。
tfさん
現在、r_sci_rxを使うのをやめ、Config_SCI5を使って試していますが、2回目の送信ができず、調べていました。
教えていただいた方法でやってみます。
割り込みを使わなくてもDMAが動作するようになりました。
2回目の送信開始時には、「IR(SCI5, TXI5) = 0;」を入れ、繰り返し送信できるようになりました。この部分をソースとして添付します。元のソースはマクロを使っており、それを展開しています。展開後にコンパイルしていませんので、重大なエラーは無いと思います。
void restart_DMA(uint8_t * tx_buf, uint16_t tx_num) { DMAC4.DMCNT.BIT.DTE = 0; //R_Config_DMAC4_Stop(); SCI5.SCR.BIT.TE = 0; // 送信停止 SCI5.SCR.BIT.TIE = 0; // 送信割込み禁止 IR(SCI5, TXI5) = 0; // 割り込み要因クリア DMAC4.DMCRA = tx_num; DMAC4.DMSAR = (uint32_t)tx_buf; DMAC4.DMCNT.BIT.DTE = 1; //R_Config_DMAC4_Start(); SCI5.SCR.BIT.TIE = 1; // 送信割込み許可 SCI5.SCR.BIT.TE = 1; // 送信起動 }
Tayaさま
2回目以降のDMACをどう起動するか、効率の良い処理はどのようになるか、ちょっと考えていました。
restart_DMA()は、SCIの送信停止処理が入っているので、完全にSCIのデータの出力が終わった後で無ければ呼び出すことが出来ないかと考えます。(もちろん、SCIのデータ出力後に呼び出されることが何からの手段で保証されるのであれば問題ありません。)
・2回目を試してみたコード
/********************************************************************************************************************** * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No * other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all * applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM * EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES * SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO * THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of * this software. By using this software, you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * * Copyright (C) 2020 Renesas Electronics Corporation. All rights reserved. *********************************************************************************************************************/ /***********************************************************************/ /* */ /* FILE :Main.c or Main.cpp */ /* DATE :Tue, Oct 31, 2006 */ /* DESCRIPTION :Main Program */ /* CPU TYPE : */ /* */ /* NOTE:THIS IS A TYPICAL EXAMPLE. */ /* */ /***********************************************************************/ //#include "typedefine.h" #include "r_smc_entry.h" #pragma address g_sci_tx_buf=0x00800000 #pragma address g_sci_rx_buf=0x00801000 unsigned char g_sci_tx_buf[0x1000]; unsigned char g_sci_rx_buf[0x1000]; volatile unsigned long g_sci_txi_count = 0; volatile unsigned long g_sci_tei_count = 0; volatile unsigned long g_sci_rxi_count = 0; volatile int g_dmac4_flag; void sci_tx_buf_copy(unsigned char *buf); #ifdef __cplusplus //#include <ios> // Remove the comment when you use ios //_SINT ios_base::Init::init_cnt; // Remove the comment when you use ios #endif void main(void); #ifdef __cplusplus extern "C" { void abort(void); } #endif void main(void) { unsigned long i; unsigned char dummy1, dummy2; //メモリ初期化 for (i=0; i<0x1000; i++) { g_sci_tx_buf[i] = 0x00; g_sci_rx_buf[i] = 0x00; } //割り込み優先度は0に設定 IPR(SCI1, RXI1) = 0; IPR(SCI1, TXI1) = 0; R_Config_SCI1_Start(); R_Config_DMAC4_Start(); R_Config_DMAC5_Start(); //受信側 DMAC5.DMCRA = 10; //受信10バイト R_Config_SCI1_Serial_Receive(&dummy1, 1); //RE=RIE=1に設定 //送信側 //1回目 sci_tx_buf_copy("SCI DMAC test\r\n"); //0x0080_0000~にコピー(15バイト) DMAC4.DMCRA = 15; //送信15バイト g_dmac4_flag = 1; R_Config_SCI1_Serial_Send(&dummy2, 1); //DMAC起動トリガ //2回目 //(1)メモリへのデータセット sci_tx_buf_copy("2nd time 0123456789\r\n"); //0x0080_000F~にコピー(21バイト) //(2)DMAC起動トリガを生じさせる準備(TXI割り込みが発生する様にする) while (SCI1.SSR.BIT.TEND == 0) { __nop(); //送信中の場合は送信完了まで待ってから送信を停止 } SCI1.SCR.BYTE &= ~0xA0U; //TE=TIE=0 (*1)を実行するための条件 ICU.IR[61].BIT.IR = 0; //1回目の最後のキャラクタ送信の際にDMACが起動されずに割り込みフラグが立っている状態となるので割り込みフラグをクリア //(*)送信間隔が短くて、1回目の送信の最後のキャラクタのTDR→内部レジスタ転送が終わる前に2回目の送信準備(DMAC起動)が整っている //場合は、本来一度TE=TIE=0にする必要はない //そうでない場合、一度TE=TIE=0として、TXI割り込みが発生する条件を整える必要がある //(3)DMACの設定 while (g_dmac4_flag) __nop(); //前回のDMACの転送が終わった後で設定 DMAC4.DMCRA = 21; //送信21バイト DMAC4.DMCNT.BIT.DTE = 1U; //次の処理のためにDMACを起動 //(4)TXI割り込みを発生させる SCI1.SCR.BYTE |= 0xA0U; //DMAC起動トリガ(*1) /* -送信間隔が短い場合(*)- →(2)(4)は無くて良い(1回目の最後のキャラクタ送信のTXIが2回目の送信のDMACを起動させる) -送信間隔が開く場合- 必ずしも上記でなければならないという事はありませんが、 余計に発生したTXI割り込みの処理と、2回目の送信にあたりTXI割り込みが生じる様にする必要があると思います */ while(1) { __nop(); } } #ifdef __cplusplus void abort(void) { } #endif void sci_tx_buf_copy(unsigned char *buf) { static unsigned long index = 0; while (*buf != '\0') { g_sci_tx_buf[index++] = *buf++; } }
・DMAC割り込みの部分
/*********************************************************************************************************************** * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all * applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT, * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability * of this software. By using this software, you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved. ***********************************************************************************************************************/ /*********************************************************************************************************************** * File Name : r_cg_dmac_user.c * Version : 1.2.120 * Device(s) : R5F5651EDxFP * Description : This file implements ISR for DMAC4 ~ DMAC7. ***********************************************************************************************************************/ /*********************************************************************************************************************** Pragma directive ***********************************************************************************************************************/ /* Start user code for pragma. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ /*********************************************************************************************************************** Includes ***********************************************************************************************************************/ #include "r_cg_macrodriver.h" #include "r_cg_dmac.h" /* Start user code for include. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ #include "r_cg_userdefine.h" /*********************************************************************************************************************** Global variables and functions ***********************************************************************************************************************/ /* Start user code for global. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ /*********************************************************************************************************************** * Function Name: r_dmac_dmac74i_interrupt * Description : This function is dmac74i interrupt service routine * Arguments : None * Return Value : None ***********************************************************************************************************************/ #if FAST_INTERRUPT_VECTOR == VECT_DMAC_DMAC74I #pragma interrupt r_dmac_dmac74i_interrupt(vect=VECT(DMAC,DMAC74I),fint) #else #pragma interrupt r_dmac_dmac74i_interrupt(vect=VECT(DMAC,DMAC74I)) #endif static void r_dmac_dmac74i_interrupt(void) { if (DMAC.DMIST.BIT.DMIS4 == 1U) { if (DMAC4.DMSTS.BIT.DTIF == 1U) { DMAC4.DMSTS.BIT.DTIF = 0U; r_dmac4_callback_transfer_end(); } } if (DMAC.DMIST.BIT.DMIS5 == 1U) { if (DMAC5.DMSTS.BIT.DTIF == 1U) { DMAC5.DMSTS.BIT.DTIF = 0U; r_dmac5_callback_transfer_end(); } } } /*********************************************************************************************************************** * Function Name: r_dmac4_dmac74i_callback_transfer_end * Description : This function is dmac4 transfer end callback function * Arguments : None * Return Value : None ***********************************************************************************************************************/ static void r_dmac4_callback_transfer_end(void) { /* Start user code for r_dmac4_dmac74i_callback_transfer_end. Do not edit comment generated here */ //DMAC4転送終了時の割り込み extern volatile int g_dmac4_flag; g_dmac4_flag = 0; /* End user code. Do not edit comment generated here */ } /*********************************************************************************************************************** * Function Name: r_dmac5_dmac74i_callback_transfer_end * Description : This function is dmac5 transfer end callback function * Arguments : None * Return Value : None ***********************************************************************************************************************/ static void r_dmac5_callback_transfer_end(void) { /* Start user code for r_dmac5_dmac74i_callback_transfer_end. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ } /* Start user code for adding. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */
・一応動いてはいる
2回目(以降)のDMACが、1回目の最後のTXI割り込みより前に起動出来れば、SCIの送信を止めなくても出力継続出来ます。(必ず間に合うタイミングで次のデータが準備できるのであれば)
1回目最後のTXIに間に合わなければ、
・SCIのTXの再起動、TXI割り込みフラグのクリア、DMACの起動、TXIを発生させる
処理が必要になるかと考えます。
間に合うか間に合わないか微妙な(どちらのパターンもある)場合(普通はこのパターンを考える必要があると思います)時にどうするのが良いのか?
・DMAC完了割り込みで、TXI割り込みを禁止、TEI割り込みを許可、DMACフラグクリア
・TEI割り込みで、SCIのTXを停止・開始、SCIフラグを立てる
・DMACを呼び出す関数(restart_DMA())でDMACフラグがクリアされていれば、DMACを起動、SCIフラグが立っていればTXIを生じさせる(フラグの準備が出来ていなければ、待つか、エラーを返す)
上記の様な処理が素直なのかな、と思いました。
参考にさせていただき、現状ソースを改善していきたいと思います。
(1)前回の送信が完了していないタイミングで次のDMACを起動する準備が整った場合
→SCIのTXは停止・再起動しない(連続送信する)
(2)送信が完了した後で次のDMACを起動する場合
→SCIを一度停止、再起動する
(1)(2)のどちらでも問題なさそうな処理をちょっと考えてみました。
(根本的に考え抜けがあるかも知れませんが)
・メイン関数サンプル
/********************************************************************************************************************** * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No * other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all * applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM * EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES * SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO * THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of * this software. By using this software, you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * * Copyright (C) 2020 Renesas Electronics Corporation. All rights reserved. *********************************************************************************************************************/ /***********************************************************************/ /* */ /* FILE :Main.c or Main.cpp */ /* DATE :Tue, Oct 31, 2006 */ /* DESCRIPTION :Main Program */ /* CPU TYPE : */ /* */ /* NOTE:THIS IS A TYPICAL EXAMPLE. */ /* */ /***********************************************************************/ //#include "typedefine.h" #include "r_smc_entry.h" volatile int g_dmac4_flag; //0:DMAC未使用, 1:DMAC使用中 volatile int g_sci1_txi_flag; //0:TX送信中or送信準備ができていない, 1:送信準備完了(TXI割り込み要求を掛けて問題ない) int sci_dmac_out(uint8_t * tx_buf, uint16_t tx_num); //SCI送信関数 #ifdef __cplusplus //#include <ios> // Remove the comment when you use ios //_SINT ios_base::Init::init_cnt; // Remove the comment when you use ios #endif void main(void); #ifdef __cplusplus extern "C" { void abort(void); } #endif void main(void) { volatile unsigned long x; unsigned char *msg[6]; R_Config_SCI1_Start(); g_sci1_txi_flag = 1; //TXI要求準備OK R_Config_DMAC4_Start(); DMAC4.DMCNT.BIT.DTE = 0U; g_dmac4_flag = 0; /* Set TXD1 pin */ PORT2.PMR.BYTE |= 0x40U; msg[0]= "SCI DMAC test 1\r\n"; msg[1]= "SCI DMAC test 2\r\n"; msg[2]= "SCI DMAC test 3\r\n"; msg[3]= "SCI DMAC test 4\r\n"; msg[4]= "SCI DMAC test 5\r\n"; msg[5]= "SCI DMAC test 6\r\n"; while(sci_dmac_out(msg[0], 17) != 0); //1回目 while(sci_dmac_out(msg[1], 17) != 0); //2回目(送信完了前にDMACの転送が間に合うタイミング) while(sci_dmac_out(msg[2], 17) != 0); //3回目(送信完了前にDMACの転送が間に合うタイミング) for (x=0; x<10000000; x++) __nop(); //長時間ウェイト while(sci_dmac_out(msg[3], 17) != 0); //4回目(送信完了前にDMACの転送が間に合わないタイミング) for (x=0; x<10000000; x++) __nop(); //長時間ウェイト while(sci_dmac_out(msg[4], 17) != 0); //5回目 while(sci_dmac_out(msg[5], 17) != 0); //6回目 while(1) { __nop(); } } #ifdef __cplusplus void abort(void) { } #endif int sci_dmac_out(uint8_t * tx_buf, uint16_t tx_num) { //SCI送信関数 //戻り値 //0: 正常終了 //1: DMAC使用中 if (g_dmac4_flag == 1) return 1; //転送アドレスと転送回数セット DMAC4.DMCRA = tx_num; DMAC4.DMSAR = (void *)tx_buf; //DMAC起動 g_dmac4_flag = 1; DMAC4.DMCNT.BIT.DTE = 1; if (g_sci1_txi_flag == 1) { //送信の準備ができている場合はTXI割り込み要求(DMAC起動トリガ)を掛ける SCI1.SCR.BYTE |= 0xA0U; g_sci1_txi_flag = 0; } return 0; }
・SCI割り込み関数
/*********************************************************************************************************************** * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all * applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT, * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability * of this software. By using this software, you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved. ***********************************************************************************************************************/ /*********************************************************************************************************************** * File Name : Config_SCI1_user.c * Component Version: 1.12.0 * Device(s) : R5F5651EDxFP * Description : This file implements device driver for Config_SCI1. ***********************************************************************************************************************/ /*********************************************************************************************************************** Pragma directive ***********************************************************************************************************************/ /* Start user code for pragma. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ /*********************************************************************************************************************** Includes ***********************************************************************************************************************/ #include "r_cg_macrodriver.h" #include "Config_SCI1.h" /* Start user code for include. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ #include "r_cg_userdefine.h" /*********************************************************************************************************************** Global variables and functions ***********************************************************************************************************************/ extern volatile uint8_t * gp_sci1_rx_address; /* SCI1 receive buffer address */ extern volatile uint16_t g_sci1_rx_count; /* SCI1 receive data number */ extern volatile uint16_t g_sci1_rx_length; /* SCI1 receive data length */ /* Start user code for global. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ /*********************************************************************************************************************** * Function Name: R_Config_SCI1_Create_UserInit * Description : This function adds user code after initializing the SCI1 channel * Arguments : None * Return Value : None ***********************************************************************************************************************/ void R_Config_SCI1_Create_UserInit(void) { /* Start user code for user init. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ } /*********************************************************************************************************************** * Function Name: r_Config_SCI1_transmit_interrupt * Description : This function is TXI1 interrupt service routine * Arguments : None * Return Value : None ***********************************************************************************************************************/ #if FAST_INTERRUPT_VECTOR == VECT_SCI1_TXI1 #pragma interrupt r_Config_SCI1_transmit_interrupt(vect=VECT(SCI1,TXI1),fint) #else #pragma interrupt r_Config_SCI1_transmit_interrupt(vect=VECT(SCI1,TXI1)) #endif static void r_Config_SCI1_transmit_interrupt(void) { r_Config_SCI1_callback_transmitend(); } /*********************************************************************************************************************** * Function Name: r_Config_SCI1_transmitend_interrupt * Description : This function is TEI1 interrupt service routine * Arguments : None * Return Value : None ***********************************************************************************************************************/ void r_Config_SCI1_transmitend_interrupt(void) { r_Config_SCI1_callback_transmitend(); } /*********************************************************************************************************************** * Function Name: r_Config_SCI1_receive_interrupt * Description : This function is RXI1 interrupt service routine * Arguments : None * Return Value : None ***********************************************************************************************************************/ #if FAST_INTERRUPT_VECTOR == VECT_SCI1_RXI1 #pragma interrupt r_Config_SCI1_receive_interrupt(vect=VECT(SCI1,RXI1),fint) #else #pragma interrupt r_Config_SCI1_receive_interrupt(vect=VECT(SCI1,RXI1)) #endif static void r_Config_SCI1_receive_interrupt(void) { if (g_sci1_rx_length > g_sci1_rx_count) { *gp_sci1_rx_address = SCI1.RDR; gp_sci1_rx_address++; g_sci1_rx_count++; } if (g_sci1_rx_length <= g_sci1_rx_count) { /* All data received */ SCI1.SCR.BIT.RIE = 0U; SCI1.SCR.BIT.RE = 0U; r_Config_SCI1_callback_receiveend(); } } /*********************************************************************************************************************** * Function Name: r_Config_SCI1_receiveerror_interrupt * Description : This function is ERI1 interrupt service routine * Arguments : None * Return Value : None ***********************************************************************************************************************/ void r_Config_SCI1_receiveerror_interrupt(void) { uint8_t err_type; r_Config_SCI1_callback_receiveerror(); /* Clear overrun, framing and parity error flags */ err_type = SCI1.SSR.BYTE; err_type &= 0xC7U; err_type |= 0xC0U; SCI1.SSR.BYTE = err_type; } /*********************************************************************************************************************** * Function Name: r_Config_SCI1_callback_transmitend * Description : This function is a callback function when SCI1 finishes transmission * Arguments : None * Return Value : None ***********************************************************************************************************************/ static void r_Config_SCI1_callback_transmitend(void) { /* Start user code for r_Config_SCI1_callback_transmitend. Do not edit comment generated here */ //スマートコンフィグレータ生成関数では、TXIとTEIどちらの割り込みもココに来てしまう extern volatile int g_sci1_txi_flag; extern volatile int g_dmac4_flag; if (SCI1.SSR.BIT.TEND == 0) { //TXI割り込み SCI1.SCR.BYTE |= 0x04; //TEIE=1 } else { //TEI割り込み SCI1.SCR.BYTE &= ~0xA4; //TE=TIE=TEIE=0 g_sci1_txi_flag = 1; //TXI要求準備OK if (g_dmac4_flag == 1) { //DMACの準備が整っている場合は送出要求 SCI1.SCR.BYTE |= 0xA0; //TE=TIE g_sci1_txi_flag = 0; } } /* End user code. Do not edit comment generated here */ } /*********************************************************************************************************************** * Function Name: r_Config_SCI1_callback_receiveend * Description : This function is a callback function when SCI1 finishes reception * Arguments : None * Return Value : None ***********************************************************************************************************************/ static void r_Config_SCI1_callback_receiveend(void) { /* Start user code for r_Config_SCI1_callback_receiveend. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ } /*********************************************************************************************************************** * Function Name: r_Config_SCI1_callback_receiveerror * Description : This function is a callback function when SCI1 reception encounters error * Arguments : None * Return Value : None ***********************************************************************************************************************/ static void r_Config_SCI1_callback_receiveerror(void) { /* Start user code for r_Config_SCI1_callback_receiveerror. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ } /* Start user code for adding. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */
・DMAC割り込み関数
/*********************************************************************************************************************** * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all * applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT, * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability * of this software. By using this software, you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved. ***********************************************************************************************************************/ /*********************************************************************************************************************** * File Name : r_cg_dmac_user.c * Version : 1.2.120 * Device(s) : R5F5651EDxFP * Description : This file implements ISR for DMAC4 ~ DMAC7. ***********************************************************************************************************************/ /*********************************************************************************************************************** Pragma directive ***********************************************************************************************************************/ /* Start user code for pragma. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ /*********************************************************************************************************************** Includes ***********************************************************************************************************************/ #include "r_cg_macrodriver.h" #include "r_cg_dmac.h" /* Start user code for include. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ #include "r_cg_userdefine.h" /*********************************************************************************************************************** Global variables and functions ***********************************************************************************************************************/ /* Start user code for global. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */ /*********************************************************************************************************************** * Function Name: r_dmac_dmac74i_interrupt * Description : This function is dmac74i interrupt service routine * Arguments : None * Return Value : None ***********************************************************************************************************************/ #if FAST_INTERRUPT_VECTOR == VECT_DMAC_DMAC74I #pragma interrupt r_dmac_dmac74i_interrupt(vect=VECT(DMAC,DMAC74I),fint) #else #pragma interrupt r_dmac_dmac74i_interrupt(vect=VECT(DMAC,DMAC74I)) #endif static void r_dmac_dmac74i_interrupt(void) { if (DMAC.DMIST.BIT.DMIS4 == 1U) { if (DMAC4.DMSTS.BIT.DTIF == 1U) { DMAC4.DMSTS.BIT.DTIF = 0U; r_dmac4_callback_transfer_end(); } } } /*********************************************************************************************************************** * Function Name: r_dmac4_dmac74i_callback_transfer_end * Description : This function is dmac4 transfer end callback function * Arguments : None * Return Value : None ***********************************************************************************************************************/ static void r_dmac4_callback_transfer_end(void) { /* Start user code for r_dmac4_dmac74i_callback_transfer_end. Do not edit comment generated here */ extern volatile int g_dmac4_flag; g_dmac4_flag = 0; /* End user code. Do not edit comment generated here */ } /* Start user code for adding. Do not edit comment generated here */ /* End user code. Do not edit comment generated here */
・実行結果