RX63T Sample Code

Hello,

I have written code to test watchdog and CMT timer but none of them are generating any interrupt.

I am using Rx63T group controller.

Can anyone kindly help me out to find the problem in my code.

Code is as follow:

#include"iodefine.h"

#include"typedefine.h"

/* Defines interrupt vector declarations */

#include "vect.h"

/* MCU clock configuration function declaration */

void ConfigureOperatingFrequency(void);

static void init_cmt_wdt (void);

/* Local WDT initialisation function prototype */

static void init_wdt(void);

void main(void);

void main(void)

{

ConfigureOperatingFrequency();

/* Initialise the CMT unit */

init_cmt_wdt();

/* Initialise the WDT unit */

init_wdt();

while(1);

}

/*******************************************************************************

* Function Name : ConfigureOperatingFrequency

* Description : Configures the clock settings for each of the device clocks

* Argument : none

* Return value : none

*******************************************************************************/

void ConfigureOperatingFrequency (void)

{

/* Declare and initialise a loop count variable */

int i = 0;

/* Protection off */

SYSTEM.PRCR.WORD = 0xA503;

/* Specify a clock stabilisation time, greater than 10ms at 12MHz (21.845 msec) */

/* XTAL = 12MHz, Period = 83.3 ns, ( {MOSCWTCR = 0x0E} 262144 * 83.3ns )= 21.845 ms */

SYSTEM.MOSCWTCR.BYTE = 0x0E;

/* 4194304 state (default)*/

/* wait over 12ms @PLL=192MHz(12MHz*16) */

SYSTEM.PLLWTCR.BYTE = 0x0F;

/* x16 @PLL */

SYSTEM.PLLCR.WORD = 0x0F00;

/* Turn on EXTAL */

SYSTEM.MOSCCR.BYTE = 0x00;

/* Turn on the PLL and enable writing to the PLL control register */

SYSTEM.PLLCR2.BYTE = 0x00;

/* Wait over 12ms */

for (i = 0; i < 2075; i++)

{

nop();

}

/* Configure the clocks as follows -

Clock Description Frequency

----------------------------------------

PLL Clock frequency...............192MHz

System Clock Frequency.............96MHz

Peripheral Module Clock B..........48MHz

FlashIF Clock......................48MHz

External Bus Clock.................48MHz */

 

SYSTEM.SCKCR.LONG = 0x21821211;

/* Set the clock source to PLL */

SYSTEM.SCKCR3.WORD = 0x0400;

/* Protection on */

SYSTEM.PRCR.WORD = 0xA500;

}

static void init_cmt_wdt (void)

{
/* Protection off */

SYSTEM.PRCR.WORD = 0xA503;

/* Cancel the CMT2 module clock stop mode */

MSTP_CMT2 = 0;

/* Protection on */

SYSTEM.PRCR.WORD = 0xA500;

/* Set CMT2 interrupt priority level to 5 */

IPR(CMT2,CMI2) = 0x5;

/* Enable CMT2 interrupts */

IEN(CMT2,CMI2) = 0x1;

/* Clear CMT2 interrupt flag */

IR(CMT2,CMI2) = 0x0;

/* Select the PCLK clock division as PCLK/512 */

CMT2.CMCR.BIT.CKS = 0x3;

/* Specify the timer period */

CMT2.CMCOR = 0x0300;

/* Enable the compare match interrupt */

CMT2.CMCR.BIT.CMIE = 0x1;

/* Start CMT2 count */

CMT.CMSTR1.BIT.STR2 = 0x1;

}

/******************************************************************************

* End of function init_cmt_wdt

******************************************************************************/

/******************************************************************************

* Function Name : init_wdt

* Description : This function initialises the WDT registers, and configures

* WDT unit to trigger an NMI interrupt when the WDT count

* underflows.

* Argument : none

* Return value : none

******************************************************************************/

static void init_wdt (void)

{

/* Set time out period to 8192 cycles

Set WDT clock divisor to PCLK/2048

Set window end position to 0%

Set window start position to 100% */

WDT.WDTCR.WORD = 0x3372;

/* Set WDT overflow to trigger NMI interrupt */

WDT.WDTRCR.BYTE = 0x00;

/* Enable WDT triggered NMI interrupt */

ICU.NMIER.BIT.WDTEN = 0x1;

/* Start WDT by refreshing the counter */

WDT.WDTRR = 0x00;

WDT.WDTRR = 0xFF;

}

/******************************************************************************

* End of function init_wdt_wdt

******************************************************************************/

// CMT2 CMI2

void Excep_CMT2_CMI2(void)

{

/* Update the CMT compare match value relative to the ADC value */

CMT2.CMCOR = 0x0300;

/* Start CMT2 count */

CMT.CMSTR1.BIT.STR2 = 0x1;

/* Refresh the WDT counter */

WDT.WDTRR = 0x00;

WDT.WDTRR = 0xFF;

}

// NMI

void NonMaskableInterrupt(void)

{

/* Start WDT by refreshing the counter */

WDT.WDTRR = 0x00;

WDT.WDTRR = 0xFF;

}

Thanks & Regards,

Prija Nair.

  • I am trying to debug in simulator mode.

  • Hallo prija,

    according to the RX Family Simulator Debugger handbook, the following peripherials are supported by the simulator:

    Timers:

    CMT timer unit (CMT0 and CMT1)

    Serial Communication Interface:

    SCI0 – SCI6

    Other peripherial functions (like the WDT) are not supported by the simulator, however CMT interrupts should fire.

    Which toolchain are you using? RENESAS or GNU?

    Kind regards,

    François

  • Hello Francois,

    Thanks for your kind reply.

    I am using renesas CC-RX Compiler.

    In the above code i am using CMT2.

    Should I change it to CMT0.

    Thanks & Regards,

    Prija Nair.

  • When you try to use on-chip peripherals and especially when you try to use interrupts you should NOT use the simulator at all but use some hardware with a real processor.

    And be sure to read the usage precautions for the emulator regarding watchdog usage. Watchdog may cause problems in the emulator.

  • Hello Francois,

      Thanks for you reply.

      In my earlier post , I got a reply stating that interrupt was generated with GNU compiler.

      Is there any problem with compilers?

    Thanks & regards,

    Prija Nair.

  • This is no question of compiler. It is a question of simulator.

    The simulator does not simulate any peripheral registers or interpret the values written to the corresponding addresses.

    There are possibilities to simulate interrupts or timer function, but this is not what you are looking for. It is NO real peripheral simulation.

    The better solution is to use a RSKRX63T or some other board with E1.

  • Following code is generating CMT0 Interrupts in my e2studio:

    #include "machine.h"    /* for nop() */

    #include "vect.h"

    #include "iodefine.h"

    void main(void);

    static void CMT_init(void);

    void main(void)

    {

       CMT_init();

       for(;;) {

           nop();

       }

    }

    static void CMT_init(void)

    {

       /* Protect off. */

       SYSTEM.PRCR.WORD = 0xA50B;

       /* Enable compare match timer 0. */

       MSTP( CMT0 ) = 0;

       /* Protect on. */

       SYSTEM.PRCR.WORD = 0xA500;

       /* Interrupt on compare match. */

       CMT0.CMCR.BIT.CMIE = 1;

       /* Set the compare match value. */

       CMT0.CMCOR = 48000;     /* 48000 => 1ms @48MHz periferial clock */

       /* Divide the PCLK by 8. */

       CMT0.CMCR.BIT.CKS = 0;

       /* Enable the interrupt... */

       IEN( CMT0, CMI0 ) = 1;

       /* ...and set its priority to the application defined kernel priority. */

       IPR( CMT0, CMI0 ) = 6;

       /* Start the timer. */

       CMT.CMSTR0.BIT.STR0 = 1;

    }

    void Excep_CMT0_CMI0(void)

    {

       nop();

    }

    In e2Studio you have to enable CMT simulation. To do so you have to:

    1. Open Debug Configurations...

    2. Select your Renesas Simulator Debugging configuration

    3. Tab "Debugger" and then tab "Debug Tool Settings"

    4. IO -> On-chip Periferial Simulation at the back of the line you can push the button with the three dots and activate CMT.

    If you are Debugging your application in Simulator, the Interrupt Service Routine Excep_CMT0_CMI0 should be called every 1 ms.

    For me this is working, I just tried it.

    Regards and good luck!

  • Thank you Francois for the reply.

    I have tried your code with the recommended setings.

    But i still face the problem of interrupt.

    I am able to see the values of CMTCNT register are being changed but it is not going into the interrupt service routine.

    And also in Debugger Tool Settings Only CMT, ICU and MPU can be enabled.

    What has to be done if we have to use MTU3 timer unit?

    Thanks & Regards,

    Prija Nair.

  • Hello Francois,

    I have one more doubt regarding this.

    Without including any code for configuring operating frequency how are you able to generate interrupt of 1ms(48Mhz)?

    When i tried to include this configuration CMTCNT was not incrementing at all.

    Can u just tell what can be the problem.

    Thanks & Regards,

    Prija Nair.

  • Interrupt is Generated

    Thank you Francois.

    I just want a reply for my last two posts.

    Thanks & Regards,

    Prija Nair.

  • Hello prija,

    as already stated before, according to the RX Family Simulator Debugger Handbook, only the following peripherials are supported by the simulator:

    Timers:

       CMT timer unit (CMT0 and CMT1)

    Serial Communication Interface:

      SCI0 – SCI6

    Other peripherial functions (like the WDT) are not supported by the simulator

    see the RX Simulator Debugger Handbook, section 2.8 (beginning at page 7 of the document):

    documentation.renesas.com/.../r20ut0445ej0100_rxsim_102u.pdf

    This means, MTU3 timer unit can't be simulated at all, you need real Hardware.

    If I get you right, the Interrupt is now generated. The only Thing you want to know how the 1ms is generated.

    In my code snippet I set the compare match value to 48000:

    CMT0.CMCOR = 48000;     /* 48000 => 1ms @48MHz periferial clock */

    To be honest, the value is not completely correct, it should be 47999 (48000 - 1) - sorry for that.

    In the comment I have written that I assume that your periferial clock was already set up at 48MHz, this code was not included in my snippet. Here is the clock configuration code I use to set up my clocks, assuming a 12MHz clock Input:

    /***********************************************************************************************************************

    Configuration Options

    ***********************************************************************************************************************/

    /*

    * Select microcontroller

    * only one should be enabled!

    */

    //#define USE_RX62x

    #define USE_RX63x

    #if defined USE_RX62x & defined USE_RX63x

    #error "only one microcontroller should be selected!"

    #endif

    #if defined USE_RX62x

    #elif defined USE_RX63x

    #else

    #error "neither USE_RX62x nor USE_RX63x are defined!"

    #endif

    /***********************************************************************************************************************

    Clock settings

    ***********************************************************************************************************************/

    /* Clock source select (CKSEL).

      0 = Low Speed On-Chip Oscillator  (LOCO)

      1 = High Speed On-Chip Oscillator (HOCO)

      2 = Main Clock Oscillator

      3 = Sub-Clock Oscillator

      4 = PLL Circuit

    */

    #define CLOCK_SOURCE (4)

    /* Clock configuration options.

      The input clock frequency is specified and then the system clocks are set by specifying the multipliers used. The

      multiplier settings are used to set the clock registers in resetprg.c. If a 12MHz clock is used and the

      ICLK is 96MHz, PCLKA is 48MHz, PCLKB is 48MHz, FCLK is 48MHz, USB Clock is 48MHz, and BCLK is 12MHz then the

      settings would be:

      XTAL_HZ = 12000000

      PLL_DIV = 1  (no division)

      PLL_MUL = 16 (12MHz x 16 = 192MHz)

      ICK_DIV =  2 : System Clock (ICLK) = (((XTAL_HZ/PLL_DIV) * PLL_MUL) / ICK_DIV)  = 96MHz

      PCKA_DIV = 4 : Peripheral Clock A (PCLKA) = (((XTAL_HZ/PLL_DIV) * PLL_MUL) / PCKA_DIV) = 48MHz

      PCKB_DIV = 4 : Peripheral Clock B (PCLKB) = (((XTAL_HZ/PLL_DIV) * PLL_MUL) / PCKB_DIV) = 48MHz

      FCK_DIV =  4 : Flash IF Clock (FCLK) = (((XTAL_HZ/PLL_DIV) * PLL_MUL) / FCK_DIV)  = 48MHz

      BCK_DIV =  8 : External Bus Clock (BCK) = (((XTAL_HZ/PLL_DIV) * PLL_MUL) / BCK_DIV)  = 24MHz

      UCK_DIV =  4 : USB Clock (UCLK) = (((XTAL_HZ/PLL_DIV) * PLL_MUL) / UCK_DIV)  = 48MHz

    */

    /* XTAL - Input clock frequency in Hz */

    #define XTAL_HZ (12000000)

    /* PLL Input Frequency Divider Select (PLIDIV).

      Available divisors = /1 (no division), /2, /4

    */

    #define PLL_DIV (1)

    /* PLL Frequency Multiplication Factor Select (STC).

      Available multipliers = x8, x10, x12, x16, x20, x24, x25, x50

    */

    #define PLL_MUL (16)

    /* System Clock Divider (ICK).

      Available divisors = /1 (no division), /2, /4, /8, /16, /32, /64

    */

    #define ICK_DIV (2)

    /* Peripheral Module Clock A Divider (PCKA).

      Available divisors = /1 (no division), /2, /4, /8, /16, /32, /64

    */

    #define PCKA_DIV (2) /* WAS 4 for 48MHz, attempting to make it equal ICLK by setting it to 2. */

    /* Peripheral Module Clock B Divider (PCKB).

      Available divisors = /1 (no division), /2, /4, /8, /16, /32, /64

    */

    #define PCKB_DIV (4)

    /* External Bus Clock Divider (BCK).

      Available divisors = /1 (no division), /2, /4, /8, /16, /32, /64

    */

    #define BCK_DIV (8)

    /* Flash IF Clock Divider (FCK).

      Available divisors = /1 (no division), /2, /4, /8, /16, /32, /64

    */

    #define FCK_DIV (4)

    /* IEBUS Clock Divider Select.

      Available divisors = /1 (no division), /2, /4, /6, /8, /16, /32, /64

    */

    #define IEBCK_DIV (8)

    /* USB Clock Divider Select.

      Available divisors = /3, /4

    */

    #define UCK_DIV (4)

    static void operating_frequency_set(void)

    {

    #if defined USE_RX62x

    unsigned long sckcr = 0;

    sckcr += (ICLK_MUL==8) ? (0ul << 24) : (ICLK_MUL==4) ? (1ul << 24) : (ICLK_MUL==2)? (2ul << 24) : (1ul << 24);

    sckcr += (BCLK_MUL==8) ? (0ul << 16) : (BCLK_MUL==4) ? (1ul << 16) : (BCLK_MUL==2)? (2ul << 16) : (1ul << 16);

    sckcr += (PCLK_MUL==8) ? (0ul <<  8) : (PCLK_MUL==4) ? (1ul <<  8) : (PCLK_MUL==2)? (2ul <<  8) : (1ul <<  8);

    SYSTEM.SCKCR.LONG = sckcr;

    #elif defined USE_RX63x

    /* Used for constructing value to write to SCKCR register. */

    unsigned long temp_clock = 0;

    volatile unsigned int i;

    /* Protect off. */

    SYSTEM.PRCR.WORD = 0xA501;

    MPC.PWPR.BIT.B0WI=0; MPC.PWPR.BIT.PFSWE=1; /* enable writing to MPC...don't disable */

    /* Uncomment if using sub-clock */

    SYSTEM.SOSCCR.BYTE = 0x01;          /* stop sub-clock */

    //SYSTEM.SOSCCR.BYTE = 0x00; /* Enable sub-clock for RTC */

    /* Wait 131,072 cycles * 12 MHz = 10.9 ms */

    SYSTEM.MOSCWTCR.BYTE = 0x0D;

    /* PLL wait is 4,194,304 cycles (default) * 192 MHz (12 MHz * 16) = 20.1 ms*/

    SYSTEM.PLLWTCR.BYTE = 0x0F;

    // Set PLL Input Divisor.

    SYSTEM.PLLCR.BIT.PLIDIV = PLL_DIV >> 1;

    // Set PLL Multiplier.

    SYSTEM.PLLCR.BIT.STC = PLL_MUL - 1;

    /* EXTAL ON */

    SYSTEM.MOSCCR.BYTE = 0x00;

    /* PLL ON */

    SYSTEM.PLLCR2.BYTE = 0x00;

    for(i = 0;i< 0x168;i++)

    {

    /* Wait over 12ms */

    }

    /* Figure out setting for FCK bits. */

    #if   FCK_DIV == 1

    /* Do nothing since FCK bits should be 0. */

    #elif FCK_DIV == 2

    temp_clock |= 0x10000000;

    #elif FCK_DIV == 4

    temp_clock |= 0x20000000;

    #elif FCK_DIV == 8

    temp_clock |= 0x30000000;

    #elif FCK_DIV == 16

    temp_clock |= 0x40000000;

    #elif FCK_DIV == 32

    temp_clock |= 0x50000000;

    #elif FCK_DIV == 64

    temp_clock |= 0x60000000;

    #else

    #error "Error! Invalid setting for FCK_DIV in platform.h"

    #endif

    /* Figure out setting for ICK bits. */

    #if   ICK_DIV == 1

    /* Do nothing since ICK bits should be 0. */

    #elif ICK_DIV == 2

    temp_clock |= 0x01000000;

    #elif ICK_DIV == 4

    temp_clock |= 0x02000000;

    #elif ICK_DIV == 8

    temp_clock |= 0x03000000;

    #elif ICK_DIV == 16

    temp_clock |= 0x04000000;

    #elif ICK_DIV == 32

    temp_clock |= 0x05000000;

    #elif ICK_DIV == 64

    temp_clock |= 0x06000000;

    #else

    #error "Error! Invalid setting for ICK_DIV in platform.h"

    #endif

    /* SDCLK Pin Output and BCLK Pin Output are disabled by default. */

    //    temp_clock |= 0x00C00000;

    /* Figure out setting for BCK bits. */

    #if   BCK_DIV == 1

    /* Do nothing since BCK bits should be 0. */

    #elif BCK_DIV == 2

    temp_clock |= 0x00010000;

    #elif BCK_DIV == 4

    temp_clock |= 0x00020000;

    #elif BCK_DIV == 8

    temp_clock |= 0x00030000;

    #elif BCK_DIV == 16

    temp_clock |= 0x00040000;

    #elif BCK_DIV == 32

    temp_clock |= 0x00050000;

    #elif BCK_DIV == 64

    temp_clock |= 0x00060000;

    #else

    #error "Error! Invalid setting for BCK_DIV in platform.h"

    #endif

    /* Figure out setting for PCKA bits. */

    #if   PCKA_DIV == 1

    /* Do nothing since PCKA bits should be 0. */

    #elif PCKA_DIV == 2

    temp_clock |= 0x00001000;

    #elif PCKA_DIV == 4

    temp_clock |= 0x00002000;

    #elif PCKA_DIV == 8

    temp_clock |= 0x00003000;

    #elif PCKA_DIV == 16

    temp_clock |= 0x00004000;

    #elif PCKA_DIV == 32

    temp_clock |= 0x00005000;

    #elif PCKA_DIV == 64

    temp_clock |= 0x00006000;

    #else

    #error "Error! Invalid setting for PCKA_DIV in platform.h"

    #endif

    /* Figure out setting for PCKB bits. */

    #if   PCKB_DIV == 1

    /* Do nothing since PCKB bits should be 0. */

    #elif PCKB_DIV == 2

    temp_clock |= 0x00000100;

    #elif PCKB_DIV == 4

    temp_clock |= 0x00000200;

    #elif PCKB_DIV == 8

    temp_clock |= 0x00000300;

    #elif PCKB_DIV == 16

    temp_clock |= 0x00000400;

    #elif PCKB_DIV == 32

    temp_clock |= 0x00000500;

    #elif PCKB_DIV == 64

    temp_clock |= 0x00000600;

    #else

    #error "Error! Invalid setting for PCKB_DIV in platform.h"

    #endif

    /* Bottom byte of SCKCR register must be set to 0x11 */

    temp_clock |= 0x00000011;

    /* Set SCKCR register. */

    SYSTEM.SCKCR.LONG = temp_clock;

    /* Re-init temp_clock to use to set SCKCR2. */

    temp_clock = 0;

    // Figure out setting for IEBCK bits.

    #if   IEBCK_DIV == 2

    temp_clock |= 0x00000001;

    #elif IEBCK_DIV == 4

    temp_clock |= 0x00000002;

    #elif IEBCK_DIV == 6

    temp_clock |= 0x0000000C;

    #elif IEBCK_DIV == 8

    temp_clock |= 0x00000003;

    #elif IEBCK_DIV == 16

    temp_clock |= 0x00000004;

    #elif IEBCK_DIV == 32

    temp_clock |= 0x00000005;

    #elif IEBCK_DIV == 64

    temp_clock |= 0x00000006;

    #else

    #error "Error! Invalid setting for IEBCK_DIV in platform.h"

    #endif

    // Figure out setting for UCK bits.

    #if   UCK_DIV == 3

    temp_clock |= 0x00000020;

    #elif UCK_DIV == 4

    temp_clock |= 0x00000030;

    #else

    #error "Error! Invalid setting for UCK_DIV in platform.h"

    #endif

    // Set SCKCR2 register.

    SYSTEM.SCKCR2.WORD = (unsigned short)temp_clock;

    /* Choose clock source. Default for platform.h is PLL. */

    SYSTEM.SCKCR3.WORD = ((unsigned short)CLOCK_SOURCE) << 8;

    /* Protect on. */

    SYSTEM.PRCR.WORD = 0xA500;

    #endif

    }