RX65Nマイコンのみでオシロは使わず(配線も無し)にRSPI波形をELC/DMA/MTU0で取ってみた(RSPI signal logger)

こんにちは。NoMaYです。

先日「CSplusのPython Console上でIronPythonスクリプトを実行して波形を描いてみた」を投稿したのですが、RX65N TBボードでRSPI波形データを収集するプログラムの作成がひと区切りついたので、プロジェクトのファイル一式を投稿します。(CC-RXのCS+版です。GNURXのe2 studio版は今週末にでも作ってみるつもりです。)

プロジェクトのファイル一式
tb_rx65n_rspi_signal_logger_ccrx_c_csplus_20190328.zip

初めはRX65NのRSPI1の入出力端子(SSL0/RSPCK/MOSI/MISO)とICUのIRQ1/5/6/7(=P31/PE5/6/7)の外部端子割り込みの入力端子とが同一端子であることを利用してプログラムを作っていましたが、ボーレートが2Mbpsだと綺麗に波形データが取れなかった為、偶然RX65Nのイベントリンクコントローラの目次を見ていて存在を知ったポートイベント機能でもRSPI1の入出力端子(SSL0/RSPCK/MOSI/MISO=PE4/5/6/7)の変化を検出することが出来ることと更に好都合にラッチまでしてくれることに気付いた時に、ポートイベント機能を使うようにプログラムを作り変えました。そして、ポートイベントでDMAを起動して、CPUクロックをカウントするように設定したMTU0のカウンタの値とポートラッチの値をRAMに順次書き込んで行くようにしました。なお、DTCを起動する版も作りましたが、2Mbpsでは綺麗な波形データは取れませんでした。ですが、ヘッダファイルの#defineで切り替えられるようになっています。ヘッダファイルで波形データ収集のOn/Offも切り替えられるようになっています。

また、今回、SPTI/SPRI/GrpAL0I/(GrpAL0Iから呼ばれる)SPIIの割り込みルーチンの先頭と末尾で関数形式マクロを呼び出して実行タイミングを波形データと一緒に収集出来るようにしてみました。こちらも、ヘッダファイルでOn/OffやDMAを使う/使わないを切り替えられるようになっています。(そして、GrpAL0I割り込み処理ルーチンが120MHz動作のRXマイコンにしては妙に時間が長いこととSPII割り込み処理ルーチンを呼び出すタイミングも妙に遅いこと、が分かって気になり始めたので、もう少し調べてから別スレッドにして投稿しようかと思っています、、、)



なお、今回のプロジェクトでは、プロジェクトの読み込み時に先日の投稿の波形を描くIronPythonスクリプト(表示されるウィンドウのサイズを変更)が今回の波形データサンプル込みで読み込まれますので、以下の画面コピーのようにPythonコンソールを開いて「Application.Run(IForm())」と入力すると波形が表示されます。



以下は今回のプログラムのスマートコンフィグレータ設定の主なところの画面コピーです。









main()のログ採取の開始から終了までは以下の通りです。

    R_Config_RSPI1_Start();

    RSPI_LOG_TIME_0();

    R_Config_MTU0_Start();

    R_Config_RSPI1_Send_Receive( rspi_send, 1, rspi_recv );
    do{}while( idle == false ); idle = false;

    nop30(); // 250ns@120MHz
    R_Config_MTU0_Stop();

    RSPI_LOG_TIME_LAST();

また、main()のあるsrc/tb_rx65n_main.cのソース全体は以下の通りです。

1817.tb_rx65n_main_c_20190328.txt
/***********************************************************************
*
*  FILE        : tb_rx65n_main.cpp
*  DATE        : 2019-02-26
*  DESCRIPTION : Main Program
*
*  NOTE:THIS IS A TYPICAL EXAMPLE.
*
***********************************************************************/
#include "RenesasRX.h"
#include "tbrx65ndef.h"
#include "RSPI_signal_log.h"
#include "stdio.h"
#include "string.h"


uint32_t rspi_send[1] = { 'A' }; /* 0x41, 0b01000001 */
uint32_t rspi_recv[1] = { '-' };
volatile bool idle = false;

volatile uint32_t GrAL0I_flags;
volatile uint32_t GrAL0I_time_isr_in;
volatile uint32_t GrAL0I_time_isr_out;


#define Printf(serial, ...)\
    do\
    {\
        uint32_t len;\
        len = snprintf( serial##_send_buff, sizeof(serial##_send_buff), __VA_ARGS__ );\
        R_Config_##serial##_Serial_Send( (uint8_t *)serial##_send_buff, len );\
        do{}while (serial##_tend == false); serial##_tend = false;\
    }while(0)

char SCI6_send_buff[128] = { 0 };
volatile bool SCI6_tend = false;


volatile uint8_t  RSPI_LOG_DMREQ_trigger_value;

volatile uint16_t RSPI_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
volatile uint8_t  RSPI_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];

volatile uint16_t * volatile RSPI_log_time_p;
volatile uint8_t  * volatile RSPI_log_port_p;

volatile uint16_t SPTI_isr_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
volatile uint8_t  SPTI_isr_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];
volatile uint16_t SPRI_isr_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
volatile uint8_t  SPRI_isr_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];
volatile uint16_t GrAL0I_isr_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
volatile uint8_t  GrAL0I_isr_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];
volatile uint16_t SPII_isr_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
volatile uint8_t  SPII_isr_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];

volatile uint16_t * volatile SPTI_isr_log_time_p;
volatile uint8_t  * volatile SPTI_isr_log_port_p;
volatile uint16_t * volatile SPRI_isr_log_time_p;
volatile uint8_t  * volatile SPRI_isr_log_port_p;
volatile uint16_t * volatile GrAL0I_isr_log_time_p;
volatile uint8_t  * volatile GrAL0I_isr_log_port_p;
volatile uint16_t * volatile SPII_isr_log_time_p;
volatile uint8_t  * volatile SPII_isr_log_port_p;


#define SHOW_LOG_INFO() show_log_info()

void show_log_info(void);
void show_log_info(void)
{
    Printf( SCI6, "\r\n" );
    Printf( SCI6, "RSPCK_Kbps = %s\r\n", RSPCK_Kbps );
    Printf( SCI6, "TICK_MHz = %d\r\n", TICK_MHz );
    Printf( SCI6, "ch = {}\r\n" );
}

#define SHOW_LOG_MORE_INFO() show_log_more_info()

void show_log_more_info(void);
void show_log_more_info(void)
{
    Printf( SCI6, "\r\n" );
    Printf( SCI6, "ns_per_dot = %s\r\n", ns_per_dot );
    Printf( SCI6, "ns_per_grid = %s\r\n", ns_per_grid );
    Printf( SCI6, "Application.Run(IForm())\r\n" );
}

#define SHOW_LOG(ch, name) show_log(ch, #name, name##_log_COUNT, name##_log_time, name##_log_port, name##_LOG_BIT)
#define SHOW_LOG_ISR(ch, name) SHOW_LOG(ch, name##_isr)

void show_log(uint8_t ch, char *name, uint16_t logcount, volatile uint16_t logtime[], volatile uint8_t logport[], uint8_t bit);
void show_log(uint8_t ch, char *name, uint16_t logcount, volatile uint16_t logtime[], volatile uint8_t logport[], uint8_t bit)
{
    Printf( SCI6, "ch[%d] = ['%s', [", ch, name );

    for( int i = 0; i < logcount; i++ )
    {
        Printf( SCI6, "[%d, %d]%s", logtime[i], (logport[i] >> bit) & 1, (i + 1 < logcount) ? ", " : "" );
    }

    Printf( SCI6, "]]\r\n" );
}

int main(void)
{
    LED0 = LED_ON;
    LED1 = LED_OFF;

    R_Config_RSPI1_Start();

    RSPI_LOG_TIME_0();

    R_Config_MTU0_Start();

    R_Config_RSPI1_Send_Receive( rspi_send, 1, rspi_recv );
    do{}while( idle == false ); idle = false;

    nop30(); // 250ns@120MHz
    R_Config_MTU0_Stop();

    RSPI_LOG_TIME_LAST();

    R_Config_SCI6_Start();

    SHOW_LOG_INFO();
#if CONFIG_RSPI_LOG_ON == 1 || CONFIG_RSPI_ISR_LOG_ON == 1
    SHOW_LOG( 0, SSL0 );
    SHOW_LOG( 1, RSPCK );
    SHOW_LOG( 2, MOSI );
    SHOW_LOG( 3, MISO );
    SHOW_LOG_ISR( 4, SPTI );
    SHOW_LOG_ISR( 5, SPRI );
    SHOW_LOG_ISR( 6, GrAL0I );
    SHOW_LOG_ISR( 7, SPII );
    SHOW_LOG_MORE_INFO();
#endif

    Printf( SCI6, "\r\n" );
    int Measurement_time = MTU0.TCNT;
    int Measurement_time_ns = Measurement_time * 1000 / TICK_MHz;
    Printf( SCI6, "# Measurement time: tick = %d (%dnsec)\r\n", Measurement_time, Measurement_time_ns );
    int GrAL0I_time_isr = GrAL0I_time_isr_out - GrAL0I_time_isr_in;
    int GrAL0I_time_isr_ns = GrAL0I_time_isr * 1000 / TICK_MHz;
    Printf( SCI6, "# GrAL0I isr in:    tick = %d\r\n", GrAL0I_time_isr_in  );
    Printf( SCI6, "# GrAL0I isr out:   tick = %d\r\n", GrAL0I_time_isr_out );
    Printf( SCI6, "# GrAL0I isr time:  tick = %d (%dnsec)\r\n", GrAL0I_time_isr, GrAL0I_time_isr_ns );
    Printf( SCI6, "# GrAL0I flags (ICU.GRPAL0.LONG) = 0x%08x\r\n", GrAL0I_flags );

    while (1)
    {
        ;
    }
}


FITのBSPモジュールのGrpAL0I割り込み処理ルーチンの先頭と最後を以下のように変更しています。

#include "RSPI_signal_log.h"
extern volatile uint32_t GrAL0I_flags;
extern volatile uint32_t GrAL0I_time_isr_in;
extern volatile uint32_t GrAL0I_time_isr_out;
#pragma interrupt group_al0_handler_isr(vect=VECT(ICU,GROUPAL0))
void group_al0_handler_isr (void)
{
#if CONFIG_RSPI_ISR_LOG_ON == 1
    RSPI_LOG_TIME_ISR_IN( GrAL0I );
#endif
    GrAL0I_flags = ICU.GRPAL0.LONG;
    GrAL0I_time_isr_in = MTU0.TCNT;

    if (1 == ICU.GRPAL0.BIT.IS9)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_SCI10_ERI10, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

途中省略

    if (1 == ICU.GRPAL0.BIT.IS20)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_RSPI2_SPII2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    GrAL0I_time_isr_out = MTU0.TCNT;
#if CONFIG_RSPI_ISR_LOG_ON == 1
    RSPI_LOG_TIME_ISR_OUT( GrAL0I );
#endif
}

また、この修正されたGrpAL0I割り込み処理ルーチンを含むsrc/r_bsp_modified/mcu_interrupt.cのソース全体は以下の通りです。

4532.mcu_interrupts_c_20190328.txt
/***********************************************************************************************************************
* 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) 2016 Renesas Electronics Corporation. All rights reserved.
***********************************************************************************************************************/
/***********************************************************************************************************************
* File Name    : mcu_interrupts.c
* Description  : This module allows for callbacks to be registered for certain interrupts.
***********************************************************************************************************************/
/**********************************************************************************************************************
* History : DD.MM.YYYY Version   Description
*         : 01.10.2016 1.00      First Release
*         : 15.05.2017 2.00      Added callback processing of the following group interrupt sources.
*                                - RIIC1_EEI1
*                                - RIIC1_TEI1
*                                - GLCDC_VPOS
*                                - GLCDC_GR1UF
*                                - GLCDC_GR2UF
*                                - DRW2D_DRW_IRQ
*                                Changed calling order of callback function in group interrupts.
*         : 27.07.2018 2.01     Added the comment to for statement.
***********************************************************************************************************************/

/***********************************************************************************************************************
Includes   <System Includes> , "Project Includes"
***********************************************************************************************************************/
/* Used for accessing CPU registers. */
#include <machine.h>
/* Access to r_bsp. */
#include "platform.h"

/***********************************************************************************************************************
Macro definitions
***********************************************************************************************************************/
/* This macro is used to suppress compiler messages about a parameter not being used in a function. The nice thing
 * about using this implementation is that it does not take any extra RAM or ROM.
 */
#define INTERNAL_NOT_USED(p)        ((void)(p))
/* Let FPSW EV, EO, EZ, EU, EX=1 (FPU exceptions enabled.) */
#define FPU_EXCEPTIONS_ENABLE       (0x00007C00)

/***********************************************************************************************************************
Typedef definitions
***********************************************************************************************************************/

/***********************************************************************************************************************
Exported global variables (to be accessed by other files)
***********************************************************************************************************************/
 
/***********************************************************************************************************************
Private global variables and functions
***********************************************************************************************************************/
/* This array holds callback functions. */
static void (* g_bsp_vectors[BSP_INT_SRC_TOTAL_ITEMS])(void * pdata);

bsp_int_err_t bsp_interrupt_enable_disable(bsp_int_src_t vector, bool enable);
bsp_int_err_t bsp_interrupt_group_enable_disable(bsp_int_src_t vector, bool enable, uint32_t ipl);

/***********************************************************************************************************************
* Function Name: bsp_interrupt_open
* Description  : Initialize callback function array.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void bsp_interrupt_open (void)
{
    uint32_t i;

    /* WAIT_LOOP */
    for (i = 0; i < BSP_INT_SRC_TOTAL_ITEMS; i++)
    {
        g_bsp_vectors[i] = FIT_NO_FUNC;
    }

    /* Initialize mapped interrupts. */
    bsp_mapped_interrupt_open();
}

/***********************************************************************************************************************
* Function Name: R_BSP_InterruptWrite
* Description  : Registers a callback function for supported interrupts. If FIT_NO_FUNC, NULL, or
*                any other invalid function address is passed for the callback argument then any previously registered
*                callbacks are unregistered. Use of FIT_NO_FUNC is preferred over NULL since access to the address
*                defined by FIT_NO_FUNC will cause a bus error which is easy for the user to catch. NULL typically
*                resolves to 0 which is a valid address on RX MCUs.
* Arguments    : vector -
*                    Which interrupt to register a callback for.
*                callback -
*                    Pointer to function to call when interrupt occurs.
* Return Value : BSP_INT_SUCCESS -
*                    Callback registered
*                BSP_INT_ERR_INVALID_ARG -
*                    Invalid function address input, any previous function has been unregistered
***********************************************************************************************************************/
bsp_int_err_t R_BSP_InterruptWrite (bsp_int_src_t vector,  bsp_int_cb_t callback)
{
    bsp_int_err_t err;

    err = BSP_INT_SUCCESS;

    /* Check for valid address. */
    if (((uint32_t)callback == (uint32_t)NULL) || ((uint32_t)callback == (uint32_t)FIT_NO_FUNC))
    {
        g_bsp_vectors[vector] = FIT_NO_FUNC;
    }
    else
    {
        g_bsp_vectors[vector] = callback;
    }

    return err;
}

/***********************************************************************************************************************
* Function Name: R_BSP_InterruptRead
* Description  : Returns the callback function address for an interrupt.
* Arguments    : vector -
*                    Which interrupt to read the callback for.
*                callback -
*                    Pointer of where to store callback address.
* Return Value : BSP_INT_SUCCESS -
*                    Callback was registered and address has been stored in 'callback' parameter.
*                BSP_INT_ERR_NO_REGISTERED_CALLBACK -
*                    No valid callback has been registered for this interrupt source.
***********************************************************************************************************************/
bsp_int_err_t R_BSP_InterruptRead (bsp_int_src_t vector, bsp_int_cb_t * callback)
{
    bsp_int_err_t err;

    err = BSP_INT_SUCCESS;

    /* Check for valid address. */
    if (((uint32_t)g_bsp_vectors[vector] == (uint32_t)NULL) || ((uint32_t)g_bsp_vectors[vector] == (uint32_t)FIT_NO_FUNC))
    {
        err = BSP_INT_ERR_NO_REGISTERED_CALLBACK;
    }
    else
    {
        *callback = g_bsp_vectors[vector];
    }

    return err;
}

/***********************************************************************************************************************
* Function Name: R_BSP_InterruptControl
* Description  : Executes specified command.
* Arguments    : vector -
*                    Which vector is being used.
*                cmd -
*                    Which command to execute.
*                pdata -
*                    Pointer to data to use with command.
*                    Currently only used for BSP_INT_CMD_GROUP_INTERRUPT_ENABLE, and points
*                    to a bsp_int_ctrl_t *. Other commands should supply FIT_NO_PTR.
* Return Value : BSP_INT_SUCCESS -
*                    Command executed successfully.
*                BSP_INT_ERR_NO_REGISTERED_CALLBACK -
*                    No valid callback has been registered for this interrupt source.
*                BSP_INT_ERR_INVALID_ARG -
*                    Invalid command sent in.
*                BSP_INT_ERR_GROUP_STILL_ENABLED -
*                    Not all group interrupts were disabled so group interrupt was not disabled.
***********************************************************************************************************************/
bsp_int_err_t R_BSP_InterruptControl (bsp_int_src_t vector, bsp_int_cmd_t cmd, void * pdata)
{
    bsp_int_err_t       err;
    bsp_int_cb_args_t   cb_args;

    err = BSP_INT_SUCCESS;

    switch (cmd)
    {
        case (BSP_INT_CMD_CALL_CALLBACK):
            if (((uint32_t)g_bsp_vectors[vector] != (uint32_t)NULL) &&
                ((uint32_t)g_bsp_vectors[vector] != (uint32_t)FIT_NO_FUNC))
            {
                /* Fill in callback info. */
                cb_args.vector = vector;

                g_bsp_vectors[vector](&cb_args);
            }
            else
            {
                err = BSP_INT_ERR_NO_REGISTERED_CALLBACK;
            }
        break;

        case (BSP_INT_CMD_INTERRUPT_ENABLE):
            err = bsp_interrupt_enable_disable(vector, true);
        break;

        case (BSP_INT_CMD_INTERRUPT_DISABLE):
            err = bsp_interrupt_enable_disable(vector, false);
        break;

        case (BSP_INT_CMD_GROUP_INTERRUPT_ENABLE):
            err = bsp_interrupt_group_enable_disable(vector, true, ((bsp_int_ctrl_t *)pdata)->ipl);
        break;

        case (BSP_INT_CMD_GROUP_INTERRUPT_DISABLE):
            err = bsp_interrupt_group_enable_disable(vector, false, 0);
        break;

        default:
            err = BSP_INT_ERR_INVALID_ARG;
        break;
    }

    return err;
}

/***********************************************************************************************************************
* Function Name: bsp_interrupt_enable_disable
* Description  : Either enables or disables an interrupt.
* Arguments    : vector -
*                    Which vector to enable or disable.
*                enable -
*                    Whether to enable or disable the interrupt.
* Return Value : BSP_INT_SUCCESS -
*                    Interrupt enabled or disabled.
*                BSP_INT_ERR_UNSUPPORTED -
*                    API does not support enabling/disabling for this vector.
***********************************************************************************************************************/
bsp_int_err_t bsp_interrupt_enable_disable (bsp_int_src_t vector, bool enable)
{
    uint32_t      temp_fpsw;
    bsp_int_err_t err = BSP_INT_SUCCESS;

    switch (vector)
    {
        case (BSP_INT_SRC_BUS_ERROR):

            if (true == enable)
            {
                /* Enable the bus error interrupt to catch accesses to illegal/reserved areas of memory */
                /* Clear any pending interrupts */
                IR(BSC,BUSERR) = 0;
                /* Make this the highest priority interrupt (adjust as necessary for your application */
                IPR(BSC,BUSERR) = 0x0F;
                /* Enable the interrupt in the ICU*/
                IEN(BSC,BUSERR) = 1;
                /* Enable illegal address interrupt in the BSC */
                BSC.BEREN.BIT.IGAEN = 1;
                /* Enable timeout detection enable. */
                BSC.BEREN.BIT.TOEN = 1;
            }
            else
            {
                /* Disable the bus error interrupt. */
                /* Disable the interrupt in the ICU*/
                IEN(BSC,BUSERR) = 0;
                /* Disable illegal address interrupt in the BSC */
                BSC.BEREN.BIT.IGAEN = 0;
                /* Disable timeout detection enable. */
                BSC.BEREN.BIT.TOEN = 0;
            }

        break;

        case (BSP_INT_SRC_EXC_FPU):

            /* Get current FPSW. */
            temp_fpsw = (uint32_t)get_fpsw();

            if (true == enable)
            {
                /* Set the FPU exception flags. */
                set_fpsw(temp_fpsw | ((uint32_t)FPU_EXCEPTIONS_ENABLE));
            }
            else
            {
                /* Clear only the FPU exception flags. */
                set_fpsw(temp_fpsw & ((uint32_t)~FPU_EXCEPTIONS_ENABLE));
            }

        break;

        case (BSP_INT_SRC_EXC_NMI_PIN):

            if (true == enable)
            {
                /* Enable NMI pin interrupt (cannot undo!) */
                ICU.NMIER.BIT.NMIEN = 1;
            }
            else
            {
                /* NMI pin interrupts cannot be disabled after being enabled. */
                err = BSP_INT_ERR_UNSUPPORTED;
            }

        break;

        default:
            err = BSP_INT_ERR_UNSUPPORTED;
        break;
    }

    return err;
}

/***********************************************************************************************************************
* Function Name: bsp_interrupt_group_enable_disable
* Description  : Either enables or disables a group interrupt. If a group interrupt is called multiple times to be
*                enabled then it will use the highest given IPL. A group interrupt will only be disabled when all
*                interrupt sources for that group are already disabled.
* Arguments    : vector -
*                    An interrupt source inside the group that is to be enabled/disabled.
*                enable -
*                    Whether to enable or disable the interrupt.
*                ipl -
*                    If enabling a group interrupt, what IPL to use.
* Return Value : BSP_INT_SUCCESS -
*                    Interrupt enabled or disabled.
*                BSP_INT_ERR_INVALID_ARG -
*                    Invalid IPL or vector
*                BSP_INT_ERR_GROUP_STILL_ENABLED -
*                    Not all group interrupts were disabled so group interrupt was not disabled.
***********************************************************************************************************************/
bsp_int_err_t bsp_interrupt_group_enable_disable (bsp_int_src_t vector, bool enable, uint32_t ipl)
{
    bsp_int_err_t err = BSP_INT_SUCCESS;

#if BSP_CFG_PARAM_CHECKING_ENABLE == 1
    /* If interrupt is going to be enabled, verify that IPL is valid. */
    if ((true == enable) && ((ipl == BSP_MCU_IPL_MIN) || (ipl > BSP_MCU_IPL_MAX)))
    {
        return BSP_INT_ERR_INVALID_ARG;
    }
#endif

    if      ((vector >= BSP_INT_SRC_BL0_SCI0_TEI0) && (vector <= BSP_INT_SRC_BL0_PDC_PCERI))
    {
        /* Group BL0. */
        if (true == enable)
        {
            IEN(ICU, GROUPBL0) = 0;
            IR(ICU, GROUPBL0)  = 0;
            IPR(ICU, GROUPBL0) = (uint8_t)(ipl > IPR(ICU, GROUPBL0) ? ipl : IPR(ICU, GROUPBL0));
            IEN(ICU, GROUPBL0) = 1;
        }
        else
        {
            /* Check to make sure all interrupt sources are already disabled for this group. */
            if (0 == ICU.GENBL0.LONG)
            {
                IEN(ICU, GROUPBL0) = 0;
                IPR(ICU, GROUPBL0) = 0;
            }
            else
            {
                err = BSP_INT_ERR_GROUP_STILL_ENABLED;
            }
        }
    }
    else if ((vector >= BSP_INT_SRC_BL1_SDHI_CDETI) && (vector <= BSP_INT_SRC_BL1_RIIC1_EEI1))
    {
        /* Group BL1. */
        if (true == enable)
        {
            IEN(ICU, GROUPBL1) = 0;
            IR(ICU, GROUPBL1)  = 0;
            IPR(ICU, GROUPBL1) = (uint8_t)(ipl > IPR(ICU, GROUPBL1) ? ipl : IPR(ICU, GROUPBL1));
            IEN(ICU, GROUPBL1) = 1;
        }
        else
        {
            /* Check to make sure all interrupt sources are already disabled for this group. */
            if (0 == ICU.GENBL1.LONG)
            {
                IEN(ICU, GROUPBL1) = 0;
                IPR(ICU, GROUPBL1) = 0;
            }
            else
            {
                err = BSP_INT_ERR_GROUP_STILL_ENABLED;
            }
        }
    }
    else if (vector == BSP_INT_SRC_BL2_SDSI_SDIOI)
    {
        /* Group BL2. */
        if (true == enable)
        {
            IEN(ICU, GROUPBL2) = 0;
            IR(ICU, GROUPBL2)  = 0;
            IPR(ICU, GROUPBL2) = (uint8_t)(ipl > IPR(ICU, GROUPBL2) ? ipl : IPR(ICU, GROUPBL2));
            IEN(ICU, GROUPBL2) = 1;
        }
        else
        {
            /* Check to make sure all interrupt sources are already disabled for this group. */
            if (0 == ICU.GENBL2.LONG)
            {
                IEN(ICU, GROUPBL2) = 0;
                IPR(ICU, GROUPBL2) = 0;
            }
            else
            {
                err = BSP_INT_ERR_GROUP_STILL_ENABLED;
            }
        }
    }
    else if ((vector >= BSP_INT_SRC_AL0_SCI10_TEI10) && (vector <= BSP_INT_SRC_AL0_RSPI2_SPEI2))
    {
        /* Group AL0. */
        if (true == enable)
        {
            IEN(ICU, GROUPAL0) = 0;
            IR(ICU, GROUPAL0)  = 0;
            IPR(ICU, GROUPAL0) = (uint8_t)(ipl > IPR(ICU, GROUPAL0) ? ipl : IPR(ICU, GROUPAL0));
            IEN(ICU, GROUPAL0) = 1;
        }
        else
        {
            /* Check to make sure all interrupt sources are already disabled for this group. */
            if (0 == ICU.GENAL0.LONG)
            {
                IEN(ICU, GROUPAL0) = 0;
                IPR(ICU, GROUPAL0) = 0;
            }
            else
            {
                err = BSP_INT_ERR_GROUP_STILL_ENABLED;
            }
        }
    }
    else if ((vector >= BSP_INT_SRC_AL1_EDMAC0_EINT0) && (vector <= BSP_INT_SRC_AL1_DRW2D_DRW_IRQ))
    {
        /* Group AL1. */
        if (true == enable)
        {
            IEN(ICU, GROUPAL1) = 0;
            IR(ICU, GROUPAL1)  = 0;
            IPR(ICU, GROUPAL1) = (uint8_t)(ipl > IPR(ICU, GROUPAL1) ? ipl : IPR(ICU, GROUPAL1));
            IEN(ICU, GROUPAL1) = 1;
        }
        else
        {
            /* Check to make sure all interrupt sources are already disabled for this group. */
            if (0 == ICU.GENAL1.LONG)
            {
                IEN(ICU, GROUPAL1) = 0;
                IPR(ICU, GROUPAL1) = 0;
            }
            else
            {
                err = BSP_INT_ERR_GROUP_STILL_ENABLED;
            }
        }
    }
    else
    {
        /* Vector given was not part of a group. */
        err = BSP_INT_ERR_INVALID_ARG;
    }

    return err;
}


/***********************************************************************************************************************
* Function Name: group_bl0_handler_isr
* Description  : Interrupt handler for Group BL0 interrupts. The way this code works is that for each possible interrupt
*                in this group the following will be performed:
*                1) Test to see if an interrupt is requested for this source
*                2) If an interrupt is requested then the registered callback is called (if one is registered)
*                NOTE: The interrupt request flag must be cleared in the peripheral.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
#pragma interrupt group_bl0_handler_isr(vect=VECT(ICU,GROUPBL0))
void group_bl0_handler_isr (void)
{
    if (1 == ICU.GRPBL0.BIT.IS1)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI0_ERI0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS0)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI0_TEI0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS3)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI1_ERI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS2)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI1_TEI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS5)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI2_ERI2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS4)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI2_TEI2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS7)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI3_ERI3, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS6)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI3_TEI3, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS9)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI4_ERI4, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS8)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI4_TEI4, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS11)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI5_ERI5, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS10)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI5_TEI5, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS13)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI6_ERI6, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS12)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI6_TEI6, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS15)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI7_ERI7, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS14)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI7_TEI7, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS17)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_ERI12, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS16)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_TEI12, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS18)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_SCIX0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS19)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_SCIX1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS20)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_SCIX2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS21)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_SCIX3, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS24)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_QSPI_QSPSSLI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS26)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_CAC_FERRI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS27)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_CAC_MENDI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS28)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_CAC_OVFI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS29)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_DOC_DOPCI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS31)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_PDC_PCERI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL0.BIT.IS30)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL0_PDC_PCFEI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }
}

/***********************************************************************************************************************
* Function Name: group_bl1_handler_isr
* Description  : Interrupt handler for Group BL1 interrupts. The way this code works is that for each possible interrupt
*                in this group the following will be performed:
*                1) Test to see if an interrupt is requested for this source
*                2) If an interrupt is requested then the registered callback is called (if one is registered)
*                NOTE: The interrupt request flag must be cleared in the peripheral.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
#pragma interrupt group_bl1_handler_isr(vect=VECT(ICU,GROUPBL1))
void group_bl1_handler_isr (void)
{
    if (1 == ICU.GRPBL1.BIT.IS3)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_SDHI_CDETI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS4)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_SDHI_CACI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS5)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_SDHI_SDACI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS6)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_MMCIF_CDETIO, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS7)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_MMCIF_ERRIO, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS8)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_MMCIF_ACCIO, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS9)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_POE3_OEI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS10)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_POE3_OEI2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS11)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_POE3_OEI3, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS12)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_POE3_OEI4, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS14)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_RIIC0_EEI0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS13)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_RIIC0_TEI0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS16)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_RIIC2_EEI2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS15)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_RIIC2_TEI2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS20)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_S12AD0_S12CMPAI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS21)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_S12AD0_S12CMPBI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS22)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_S12AD1_S12CMPAI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS23)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_S12AD1_S12CMPBI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS25)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_SCI8_ERI8, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS24)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_SCI8_TEI8, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS27)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_SCI9_ERI9, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS26)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_SCI9_TEI9, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS29)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_RIIC1_EEI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPBL1.BIT.IS28)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL1_RIIC1_TEI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

}

/***********************************************************************************************************************
* Function Name: group_bl2_handler_isr
* Description  : Interrupt handler for Group BL1 interrupts. The way this code works is that for each possible interrupt
*                in this group the following will be performed:
*                1) Test to see if an interrupt is requested for this source
*                2) If an interrupt is requested then the registered callback is called (if one is registered)
*                NOTE: The interrupt request flag must be cleared in the peripheral.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
#pragma interrupt group_bl2_handler_isr(vect=VECT(ICU,GROUPBL2))
void group_bl2_handler_isr (void)
{
    if (1 == ICU.GRPBL2.BIT.IS0)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_BL2_SDSI_SDIOI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

}

/***********************************************************************************************************************
* Function Name: group_al0_handler_isr
* Description  : Interrupt handler for Group AL0 interrupts. The way this code works is that for each possible interrupt
*                in this group the following will be performed:
*                1) Test to see if an interrupt is requested for this source
*                2) If an interrupt is requested then the registered callback is called (if one is registered)
*                NOTE: The interrupt request flag must be cleared in the peripheral.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
#include "RSPI_signal_log.h"
extern volatile uint32_t GrAL0I_flags;
extern volatile uint32_t GrAL0I_time_isr_in;
extern volatile uint32_t GrAL0I_time_isr_out;
#pragma interrupt group_al0_handler_isr(vect=VECT(ICU,GROUPAL0))
void group_al0_handler_isr (void)
{
#if CONFIG_RSPI_ISR_LOG_ON == 1
    RSPI_LOG_TIME_ISR_IN( GrAL0I );
#endif
    GrAL0I_flags = ICU.GRPAL0.LONG;
    GrAL0I_time_isr_in = MTU0.TCNT;

    if (1 == ICU.GRPAL0.BIT.IS9)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_SCI10_ERI10, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL0.BIT.IS8)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_SCI10_TEI10, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL0.BIT.IS13)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_SCI11_ERI11, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL0.BIT.IS12)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_SCI11_TEI11, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

   if (1 == ICU.GRPAL0.BIT.IS17)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_RSPI0_SPEI0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL0.BIT.IS16)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_RSPI0_SPII0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL0.BIT.IS19)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_RSPI1_SPEI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL0.BIT.IS18)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_RSPI1_SPII1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL0.BIT.IS21)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_RSPI2_SPEI2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL0.BIT.IS20)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL0_RSPI2_SPII2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    GrAL0I_time_isr_out = MTU0.TCNT;
#if CONFIG_RSPI_ISR_LOG_ON == 1
    RSPI_LOG_TIME_ISR_OUT( GrAL0I );
#endif
}

/***********************************************************************************************************************
* Function Name: group_al1_handler_isr
* Description  : Interrupt handler for Group AL1 interrupts. The way this code works is that for each possible interrupt
*                in this group the following will be performed:
*                1) Test to see if an interrupt is requested for this source
*                2) If an interrupt is requested then the registered callback is called (if one is registered)
*                NOTE: The interrupt request flag must be cleared in the peripheral.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
#pragma interrupt group_al1_handler_isr(vect=VECT(ICU,GROUPAL1))
void group_al1_handler_isr (void)
{
    if (1 == ICU.GRPAL1.BIT.IS4)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL1_EDMAC0_EINT0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL1.BIT.IS9)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL1_GLCDC_GR1UF, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL1.BIT.IS10)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL1_GLCDC_GR2UF, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL1.BIT.IS8)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL1_GLCDC_VPOS, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    if (1 == ICU.GRPAL1.BIT.IS11)
    {
        R_BSP_InterruptControl(BSP_INT_SRC_AL1_DRW2D_DRW_IRQ, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

}



RSPI波形データ収集プログラムのヘッダファイルのコンフィグレーション部分は以下の通りです。

#define CONFIG_RSPI_LOG_BUFF_SIZE     256

#define CONFIG_RSPI_LOG_ON            1  // 0 or 1
#define CONFIG_RSPI_LOG_DMA           1  // 0 or 1 --.__ exclusive
#define CONFIG_RSPI_LOG_DTC           0  // 0 or 1 --'
#define CONFIG_RSPI_LOG_INT           0  // 0 only ----- obsolete

#define CONFIG_RSPI_ISR_LOG_ON        0  // 0 or 1
#define CONFIG_RSPI_ISR_LOG_WITH_DMA  0  // 0 or 1 --.__ exclusive
#define CONFIG_RSPI_ISR_LOG_PRG_ONLY  0  // 0 or 1 --'

また、このヘッダファイル(src/RSPI_signal_log.h)はRSPI波形データ収集プログラムの主な実装も含んでいて、そのソース全体は以下の通りです。

3073.RSPI_signal_log_h_20190328.txt
/*
 * RSPI signal logger
 */

#define CONFIG_RSPI_LOG_BUFF_SIZE     256

#define CONFIG_RSPI_LOG_ON            1  // 0 or 1
#define CONFIG_RSPI_LOG_DMA           1  // 0 or 1 --.__ exclusive
#define CONFIG_RSPI_LOG_DTC           0  // 0 or 1 --'
#define CONFIG_RSPI_LOG_INT           0  // 0 only ----- obsolete

#define CONFIG_RSPI_ISR_LOG_ON        0  // 0 or 1
#define CONFIG_RSPI_ISR_LOG_WITH_DMA  0  // 0 or 1 --.__ exclusive
#define CONFIG_RSPI_ISR_LOG_PRG_ONLY  0  // 0 or 1 --'

#if (CONFIG_RSPI_LOG_ON == 1 && (CONFIG_RSPI_LOG_DMA == 1 || CONFIG_RSPI_LOG_DTC == 1))\
 || (CONFIG_RSPI_ISR_LOG_ON == 1 && CONFIG_RSPI_ISR_LOG_WITH_DMA == 1)
#define CONFIG_RSPI_LOG_BUS_PRIORITY  0x0151  // Reduce CPU bus (internal main bus 1) waiting time
#else
#define CONFIG_RSPI_LOG_BUS_PRIORITY  0x0000  // RX MCU default
#endif
/*
 * 0x0000 : All(External bus, Peripheral bus 6, {4, 5}, {2, 3}, 1, Memory bus 2, {1, 3}) - fixed priority
 * 0x0151 : Peripheral bus {4, 5}, {2, 3}, 1, Memory bus {1, 3} - round robin priority
 *
 * Memory bus 1: RAM
 * Memory bus 2: CODE FLASH
 * Memory bus 3: Extended RAM
 * Peripheral bus 1: DTC, DMAC, EXDMAC, ICU, Bus Error Monitor
 * Peripheral bus 2: other than 1, 3, 4, 5
 * Peripheral bus 3: USBb, PDC, Standby RAM
 * Peripheral bus 4: EDMAC, ETHERC, MTU3, SCIi, RSPI, AES
 * Peripheral bus 5: GLCDC, DRW2D
 * Peripheral bus 6: CODE FLASH (P/E), DATA FLASH
 * External bus: External Memory
 */


#define TICK_MHz 120
#if 1
#define RSPCK_Kbps  "2000"
#define ns_per_dot  "12.5"
#define ns_per_grid "1000"
#elif 0
#define RSPCK_Kbps  "1000"
#define ns_per_dot  "25"
#define ns_per_grid "1000"
#elif 0
#define RSPCK_Kbps  "500"
#define ns_per_dot  "50"
#define ns_per_grid "2000"
#endif


extern volatile uint8_t  RSPI_LOG_DMREQ_trigger_value;

extern volatile uint16_t RSPI_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
extern volatile uint8_t  RSPI_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];

#define SSL0_log_time   RSPI_log_time
#define SSL0_log_port   RSPI_log_port
#define RSPCK_log_time  RSPI_log_time
#define RSPCK_log_port  RSPI_log_port
#define MOSI_log_time   RSPI_log_time
#define MOSI_log_port   RSPI_log_port
#define MISO_log_time   RSPI_log_time
#define MISO_log_port   RSPI_log_port

#define SSL0_LOG_BIT   4
#define RSPCK_LOG_BIT  5
#define MOSI_LOG_BIT   6
#define MISO_LOG_BIT   7

#define SSL0_log_COUNT   (RSPI_LOG_LAST + 1)
#define RSPCK_log_COUNT  (RSPI_LOG_LAST + 1)
#define MOSI_log_COUNT   (RSPI_LOG_LAST + 1)
#define MISO_log_COUNT   (RSPI_LOG_LAST + 1)


#if CONFIG_RSPI_LOG_ON == 1


#define RSPI_LOG_TIME   MTU0.TCNT
#define SSL0_LOG_TIME   MTU0.TCNT
#define RSPCK_LOG_TIME  MTU0.TCNT
#define MOSI_LOG_TIME   MTU0.TCNT
#define MISO_LOG_TIME   MTU0.TCNT

#define RSPI_LOG_PORT   ELC.PDBF2.BYTE
#define SSL0_LOG_PORT   ELC.PDBF2.BYTE
#define RSPCK_LOG_PORT  ELC.PDBF2.BYTE
#define MOSI_LOG_PORT   ELC.PDBF2.BYTE
#define MISO_LOG_PORT   ELC.PDBF2.BYTE

#define RSPI_LOG_PORT_0LAST   PORTE.PIDR.BYTE
#define SSL0_LOG_PORT_0LAST   PORTE.PIDR.BYTE
#define RSPCK_LOG_PORT_0LAST  PORTE.PIDR.BYTE
#define MOSI_LOG_PORT_0LAST   PORTE.PIDR.BYTE
#define MISO_LOG_PORT_0LAST   PORTE.PIDR.BYTE

#if CONFIG_RSPI_LOG_DMA == 1

#define RSPI_LOG_LAST  (1 + ((CONFIG_RSPI_LOG_BUFF_SIZE - 2) - DMAC0.DMCRB))

#define _RSPI_LOG_START()\
    do\
    {\
        R_Config_DMAC6_TRGbyDMAC0_Start();\
        R_Config_DMAC7_TRGbyDMAC0_Start();\
        R_Config_DMAC0_ELSR18I_Start();\
        R_Config_ELC_Start();\
    }while(0)

#define _RSPI_LOG_STOP()\
    do\
    {\
        R_Config_ELC_Stop();\
        R_Config_DMAC0_ELSR18I_Stop();\
        R_Config_DMAC6_TRGbyDMAC0_Stop();\
        R_Config_DMAC7_TRGbyDMAC0_Stop();\
    }while(0)

#elif CONFIG_RSPI_LOG_DTC == 1

#define RSPI_LOG_LAST  (1 + ((CONFIG_RSPI_LOG_BUFF_SIZE - 2) - (dtc_transferdata_vector193[0].cra_crb >> 16)))

#define _RSPI_LOG_START()\
    do\
    {\
        R_Config_DTC_ELSR18I_Start();\
        R_Config_ELC_Start();\
    }while(0)

#define _RSPI_LOG_STOP()\
    do\
    {\
        R_Config_ELC_Stop();\
        R_Config_DTC_ELSR18I_Stop();\
    }while(0)

#endif

#define _RSPI_LOG_0()\
    do\
    {\
        RSPI_log_time[0] = 0;\
        RSPI_log_port[0] = RSPI_LOG_PORT_0LAST;\
        RSPI_log_time_p = RSPI_log_time + 1;\
        RSPI_log_port_p = RSPI_log_port + 1;\
        _RSPI_LOG_START();\
    }while(0)

#define _RSPI_LOG_LAST()\
    do\
    {\
        RSPI_log_time[RSPI_LOG_LAST] = RSPI_LOG_TIME;\
        RSPI_log_port[RSPI_LOG_LAST] = RSPI_LOG_PORT_0LAST;\
        _RSPI_LOG_STOP();\
    }while(0)


#elif !(CONFIG_RSPI_LOG_ON == 1)


#define RSPI_LOG_LAST   (-1)
#define SSL0_LOG_LAST   (-1)
#define RSPCK_LOG_LAST  (-1)
#define MOSI_LOG_LAST   (-1)
#define MISO_LOG_LAST   (-1)

#define _RSPI_LOG_0()    do{}while(0)
#define _RSPI_LOG_LAST() do{}while(0)


#endif


extern volatile uint16_t SPTI_isr_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
extern volatile uint8_t  SPTI_isr_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];
extern volatile uint16_t SPRI_isr_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
extern volatile uint8_t  SPRI_isr_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];
extern volatile uint16_t GrAL0I_isr_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
extern volatile uint8_t  GrAL0I_isr_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];
extern volatile uint16_t SPII_isr_log_time[CONFIG_RSPI_LOG_BUFF_SIZE];
extern volatile uint8_t  SPII_isr_log_port[CONFIG_RSPI_LOG_BUFF_SIZE];

extern volatile uint16_t * volatile SPTI_isr_log_time_p;
extern volatile uint8_t  * volatile SPTI_isr_log_port_p;
extern volatile uint16_t * volatile SPRI_isr_log_time_p;
extern volatile uint8_t  * volatile SPRI_isr_log_port_p;
extern volatile uint16_t * volatile GrAL0I_isr_log_time_p;
extern volatile uint8_t  * volatile GrAL0I_isr_log_port_p;
extern volatile uint16_t * volatile SPII_isr_log_time_p;
extern volatile uint8_t  * volatile SPII_isr_log_port_p;

#define SPTI_isr_LOG_BIT    0
#define SPRI_isr_LOG_BIT    0
#define GrAL0I_isr_LOG_BIT  0
#define SPII_isr_LOG_BIT    0

#define SPTI_isr_log_COUNT    (SPTI_ISR_LOG_LAST   + 1)
#define SPRI_isr_log_COUNT    (SPRI_ISR_LOG_LAST   + 1)
#define GrAL0I_isr_log_COUNT  (GrAL0I_ISR_LOG_LAST + 1)
#define SPII_isr_log_COUNT    (SPII_ISR_LOG_LAST   + 1)


#if CONFIG_RSPI_ISR_LOG_ON == 1

#ifndef RSPI_LOG_TIME
#define RSPI_LOG_TIME  MTU0.TCNT
#endif

#if CONFIG_RSPI_ISR_LOG_WITH_DMA == 1

#define SPTI_ISR_LOG_DMAC    DMAC1
#define SPRI_ISR_LOG_DMAC    DMAC2
#define GrAL0I_ISR_LOG_DMAC  DMAC3
#define SPII_ISR_LOG_DMAC    DMAC4

#define SPTI_ISR_LOG_LAST    ((uint16_t *)SPTI_ISR_LOG_DMAC.DMDAR   - SPTI_isr_log_time)
#define SPRI_ISR_LOG_LAST    ((uint16_t *)SPRI_ISR_LOG_DMAC.DMDAR   - SPRI_isr_log_time)
#define GrAL0I_ISR_LOG_LAST  ((uint16_t *)GrAL0I_ISR_LOG_DMAC.DMDAR - GrAL0I_isr_log_time)
#define SPII_ISR_LOG_LAST    ((uint16_t *)SPII_ISR_LOG_DMAC.DMDAR   - SPII_isr_log_time)

#elif CONFIG_RSPI_ISR_LOG_PRG_ONLY == 1

#define SPTI_ISR_LOG_LAST    (SPTI_isr_log_time_p   - SPTI_isr_log_time)
#define SPRI_ISR_LOG_LAST    (SPRI_isr_log_time_p   - SPRI_isr_log_time)
#define GrAL0I_ISR_LOG_LAST  (GrAL0I_isr_log_time_p - GrAL0I_isr_log_time)
#define SPII_ISR_LOG_LAST    (SPII_isr_log_time_p   - SPII_isr_log_time)

#endif

#pragma inline_asm RSPI_ISR_LOG_SPLIT_CODE_DOMAIN
static void RSPI_ISR_LOG_SPLIT_CODE_DOMAIN(void){}

#if CONFIG_RSPI_ISR_LOG_WITH_DMA == 1

#define RSPI_LOG_TIME_ISR_IN(name)\
    do\
    {\
        name##_ISR_LOG_DMAC.DMREQ.BYTE = 1;\
        RSPI_ISR_LOG_SPLIT_CODE_DOMAIN();\
    }while(0)

#define RSPI_LOG_TIME_ISR_OUT(name)\
    do\
    {\
        RSPI_ISR_LOG_SPLIT_CODE_DOMAIN();\
        name##_ISR_LOG_DMAC.DMREQ.BYTE = 1;\
    }while(0)

#define RSPI_LOG_TIME_ISR_ONESHOT(name) /* TODO */

#define _RSPI_ISR_LOG_START()\
    do\
    {\
        R_Config_DMAC1_Start();\
        R_Config_DMAC2_Start();\
        R_Config_DMAC3_Start();\
        R_Config_DMAC4_Start();\
    }while(0)

#define _RSPI_ISR_LOG_STOP()\
    do\
    {\
        R_Config_DMAC1_Stop();\
        R_Config_DMAC2_Stop();\
        R_Config_DMAC3_Stop();\
        R_Config_DMAC4_Stop();\
    }while(0)

#elif CONFIG_RSPI_ISR_LOG_PRG_ONLY == 1

#define RSPI_LOG_TIME_ISR_IN(name)\
    do\
    {\
        *(*(uint16_t **)&name##_isr_log_time_p) = RSPI_LOG_TIME;\
        RSPI_ISR_LOG_SPLIT_CODE_DOMAIN();\
    }while(0)

#define RSPI_LOG_TIME_ISR_OUT(name)\
    do\
    {\
        RSPI_ISR_LOG_SPLIT_CODE_DOMAIN();\
        *((*(uint16_t **)&name##_isr_log_time_p += 2) - 1) = RSPI_LOG_TIME;\
    }while(0)

#define RSPI_LOG_TIME_ISR_ONESHOT(name) /* TODO */

#define _RSPI_ISR_LOG_START() do{}while(0)

#define _RSPI_ISR_LOG_STOP()  do{}while(0)

#endif

#define _RSPI_ISR_LOG_0_(name)\
    do\
    {\
        name##_isr_log_time[0] = 0;\
        name##_isr_log_port[0] = 0;\
        name##_isr_log_time_p = name##_isr_log_time + 1;\
        name##_isr_log_port_p = name##_isr_log_port + 1;\
    }while(0)


#define _RSPI_ISR_LOG_0()\
    do\
    {\
        _RSPI_ISR_LOG_0_(SPTI);\
        _RSPI_ISR_LOG_0_(SPRI);\
        _RSPI_ISR_LOG_0_(GrAL0I);\
        _RSPI_ISR_LOG_0_(SPII);\
        _RSPI_ISR_LOG_START();\
    }while(0)

#define _RSPI_ISR_LOG_LAST_(name)\
    do\
    {\
        name##_isr_log_time[name##_ISR_LOG_LAST] = RSPI_LOG_TIME;\
        name##_isr_log_port[name##_ISR_LOG_LAST] = 0;\
        for (int i = 1; i < name##_ISR_LOG_LAST; i++)\
        {\
            name##_isr_log_port[i] = (i & 1);\
        }\
    }while(0)

#define _RSPI_ISR_LOG_LAST()\
    do\
    {\
        _RSPI_ISR_LOG_LAST_(SPTI);\
        _RSPI_ISR_LOG_LAST_(SPRI);\
        _RSPI_ISR_LOG_LAST_(GrAL0I);\
        _RSPI_ISR_LOG_LAST_(SPII);\
        _RSPI_ISR_LOG_STOP();\
    }while(0)


#elif !(CONFIG_RSPI_ISR_LOG_ON == 1)


#define SPTI_ISR_LOG_LAST    (-1)
#define SPRI_ISR_LOG_LAST    (-1)
#define GrAL0I_ISR_LOG_LAST  (-1)
#define SPII_ISR_LOG_LAST    (-1)

#define RSPI_LOG_TIME_ISR_IN(name)       do{}while(0)
#define RSPI_LOG_TIME_ISR_OUT(name)      do{}while(0)
#define RSPI_LOG_TIME_ISR_ONESHOT(name)  do{}while(0)
#define _RSPI_ISR_LOG_0()                do{}while(0)
#define _RSPI_ISR_LOG_LAST()             do{}while(0)


#endif


#define RSPI_LOG_TIME_0()\
    do\
    {\
        BSC.BUSPRI.WORD = CONFIG_RSPI_LOG_BUS_PRIORITY;\
        _RSPI_LOG_0();\
        _RSPI_ISR_LOG_0();\
    }while(0)

#define RSPI_LOG_TIME_LAST()\
    do\
    {\
        _RSPI_LOG_LAST();\
        _RSPI_ISR_LOG_LAST();\
    }while(0)