Chapter 26_Renesas MCU Zero-Based Introductory Tutorial Series - Independent Watchdog Timer-IWDT

This tutorial is written based on the DShanMCU-RA6M5 development board produced by Wei Dongshan Baiwen.com . Students who need it can get it here: https://item.taobao.com/item.htm?id=728461040949

Obtain supporting information: https://renesas-docs.100ask.net

Summary of Renesas MCU zero-based entry series tutorials : https://blog.csdn.net/qq_35181236/article/details/132779862


Chapter 26 Independent Watchdog Timer-IWDT

Objectives of this chapter

  • Understand the watchdog timer of the A6M5 processor and its working principle;
  • Learn to use RASC to configure the watchdog timer and use its interface functions;

26.1 WDT peripherals of RA6M5

26.1.1 Characteristics of WDT

IWDT (Independent Watchdog Timer) consists of a 14-bit down counter that can recover applications from errors (such as restarting the system). The application must refresh the timer within the allowed counting window. If the counter underflows, the IWDT will reset the MCU or generate a non-maskable interrupt (NMI).

The characteristics of the watchdog timer of the Renesas RA6M5 processor are shown in the table below:

The clock source of the independent watchdog is an independent clock IWDTCLK. The maximum clock frequency of PCLKB is 15kHz. You can use RASC to set the frequency division coefficient of IWDTCLK in the BSP.

26.1.2 System block diagram of IWDT

The system block diagram of IWDT is shown in the figure below:

26.1.3 Similarities and differences between IWDT and WDT

  1. Difference

The differences between the independent watchdog (IWDT) and the watchdog (WDT) of the Renesas RA6M5 are as follows:

  • The clock sources are different. WDT uses an external clock circuit as the clock source, while IWDT has its own clock source;
  • WDT has two modes: register start and self-start, while IWDT only has self-start mode;
  1. Same point

Independent watchdog (IWDT) and watchdog (WDT) also have many similarities, mainly as follows:

  • You can select the reset range (window value);
  • You can set whether to start in sleep mode;
  • NMI interrupt and reset restart can be set;

26.1.4 Working principle of IWDT

  1. Timeout calculation

Taking IWDTCLK=15kHz as an example, assume that the IWDT is configured as follows:

  • Frequency division coefficient bit 256
  • The timeout period is 2048cycles

Then the timeout time of IWDT is:

image3

  1. Running status analysis

In the "Option Function Select Register 0" register, there is a mode selection bit [OFS0.IWDTSTRT] for IWDT: when it is written to 0, the automatic start mode of IWDT is enabled; writing to 1 turns off the counting of IWDT.

Only in reset state, the following settings of IWDT in OFS0 will be effective:

  • Configure OFS0.IWDTCKS[3:0] to configure the clock division coefficient of IWDT;
  • Configure OFS0.IWDTRPSS[1:0] and OFS0.IWDTRPES[1:0] to set the beginning and end positions of IWDT window monitoring;
  • Configure OFS0.IWDTTOPS[1:0] to set the IWDT timeout period value cycles;
  • Configure OFS0.IWDTRSTIRQS to enable the reset output and interrupt request of IWDT;

When the reset state ends, the IWDT counter will count down immediately. An example of IWDT window refresh is shown in the RA6M5 user manual:

To sum it up:

  • Refreshing the watchdog during the window period will cause the IWDT counter to count again and will not trigger any events or interrupts;
  • Refreshing at the starting position of the window period will trigger a refresh error event and trigger an NMI interrupt;
  • Refreshing when the end of the window is exceeded but the count does not overflow will trigger a refresh error event and trigger an NMI interrupt;
  • If the IWDT count overflows, the technology overflow event will be triggered and the NMI interrupt will be triggered;

In other words, if window monitoring is used, the system will run normally only if the timer is refreshed during the window period, otherwise the NMI interrupt will be triggered.

26.2 Use of IWDT module

26.2.1 Module configuration

  1. Add IWDT Stack

The steps to add the IWDT module in FSP Stacks are as shown in the figure below:

  1. Configure IWDT in BSP

From the previous analysis of the working principle of IWDT, we can see that all operations of IWDT are configured in the OFS0 register, and OFS0 is in the "RA6F5 Family" in the BSP module, as shown in the following figure:

  • Start Mode Select: IWDT startup mode selection

1.1 IWDT is automatically activated after a reset (Autostart mode)(自启动)
1.2 IWDT is Disabled

  • Timeout Period: IWDT counting period value

1.1 128 cycles
1.2 512 cycles
1.3 1024 cycles
1.4 2048 cycles

  • Dedicated Clock Frequency Divisor: IWDT clock division coefficient (1/16/32/64/128/256), default 128;
  • Window End Position: Window monitoring end position, default 0%, no end position
  • Window Start Position: window monitoring start position, default 100%, no start position
  • Reset Interrupt Request: Select to enable the interrupt request that triggers reset (NMI or Reset)
  • Stop Control: Conditions for stopping WDT control

1.1 Stop counting when in Sleep, Snooze mode, or Software Standby
1.2 Counting continues (Note: Device will not enter Deep Standby Mode when selected. Device will enter Software Standby Mode)

If the user chooses to use the NMI interrupt, he also needs to find the IWDG Stack module in the Stacks of RASC and set the NMI interrupt callback function name, as shown in the following figure:

26.2.2 Interpretation of configuration information

After configuring IWDT in RASC and generating the project, the structure global constant g_iwdt will be generated in hal_data.c, which is used to represent the IWDT device. The code is as follows:

const wdt_instance_t g_wdt =
{
    
    
    .p_ctrl        = &g_iwdt_ctrl,
    .p_cfg         = &g_iwdt_cfg,
    .p_api         = &g_wdt_on_iwdt
};
  • p_ctrl: iwdt_instance_ctrl_t type pointer member, used to record device status and record some important information (such as callback functions);
  • p_cfg: Points to the configuration structure of IWDT. The value of this structure comes from the configuration of IWDT in RASC. The code is as follows:
const wdt_cfg_t g_iwdt_cfg =
{
    
    
    .timeout = 0,
    .clock_division = 0,
    .window_start = 0,
    .window_end = 0,
    .reset_control = 0,
    .stop_control = 0,
    .p_callback = nmi_callback,
};
  • p_api: Points to a wdt_api_t structure. This structure is implemented in r_iwdt.c. It encapsulates the interface function of the IWDT device. The code is as follows:
const wdt_api_t g_wdt_on_iwdt =
{
    
    
    .open        = R_IWDT_Open,
    .refresh     = R_IWDT_Refresh,
    .statusGet   = R_IWDT_StatusGet,
    .statusClear = R_IWDT_StatusClear,
    .counterGet  = R_IWDT_CounterGet,
    .timeoutGet  = R_IWDT_TimeoutGet,
    .callbackSet = R_IWDT_CallbackSet,
};

26.2.3 Interrupt callback function

The IWDT interrupt callback function name is configured in RASC, and this callback function will be declared in hal_data.h:

#ifndef nmi_callback
void nmi_callback(wdt_callback_args_t * p_args);
#endif

Users need to implement this callback function, for example:

void nmi_callback(wdt_callback_args_t * p_args)
{
    
    
    (void)p_args;
}

26.2.4 API interface and its usage

As mentioned before, the wdt_api_t structure is used in the FSP library function to encapsulate the IWDT operation method. The prototype is as follows:

typedef struct st_wdt_api
{
    
    
    fsp_err_t (* open)(wdt_ctrl_t * const p_ctrl, wdt_cfg_t const * const p_cfg);
    fsp_err_t (* refresh)(wdt_ctrl_t * const p_ctrl);
    fsp_err_t (* statusGet)(wdt_ctrl_t * const p_ctrl, wdt_status_t * const p_status);
    fsp_err_t (* statusClear)(wdt_ctrl_t * const p_ctrl, const wdt_status_t status);
    fsp_err_t (* counterGet)(wdt_ctrl_t * const p_ctrl, uint32_t * const p_count);
    fsp_err_t (* timeoutGet)(wdt_ctrl_t * const p_ctrl, 
                             wdt_timeout_values_t * const p_timeout);
    fsp_err_t (* callbackSet)(wdt_ctrl_t * const p_api_ctrl, 
                              void (* p_callback)(wdt_callback_args_t *),
                              void const * const p_context, 
                              wdt_callback_args_t * const p_callback_memory);
} wdt_api_t;

Renesas implements a wdt_api_t structure in r_iwdt.c. IWDT and WDT share a set of operating interfaces. Readers please refer to "25.2.4 API Interface and Its Usage" to understand the usage of these functions.

26.3 Independent watchdog timer experiment

26.3.1 Design purpose

Let users learn to use the IWDT of Renesas RA6M5 and observe whether the watchdog is refreshed.

26.3.2 Hardware connection

This experiment will use the onboard serial port and buttons, please refer to the previous configuration.

26.3.3 Drivers

  1. Initialize IWDT

Call the open function to initialize IWDT and start it. The code is as follows:

void IWDTDrvInit(void)
{
    
    
    fsp_err_t err = g_iwdt.p_api->open(g_iwdt.p_ctrl, g_iwdt.p_cfg);
    assert(FSP_SUCCESS == err);
}
  1. Refresh IWDT

Refreshing IWDT is relatively simple, just call its refresh function directly:

void IWDTDrvRefresh(void)
{
    
    
    fsp_err_t err = g_iwdt.p_api->refresh(g_iwdt.p_ctrl);
    assert(FSP_SUCCESS == err);
}
  1. NMI interrupt callback function

If the NMI interrupt of IWDT is enabled in RASC, you need to implement the NMI callback function yourself. The code is as follows:

__WEAK void DataSaveProcess(void)
{
    
    
}
void nmi_callback(wdt_callback_args_t * p_args)
{
    
    
    (void)p_args;
    printf("\r\nWarning!Do your most important save working!!\r\n");
    DataSaveProcess();
}
  1. Key refresh timer

After the button debounce processing, the watchdog timer is refreshed. The code is as follows:

void KeyProcessEvents(void)
{
    
    
    struct IODev *ptLedDev = IOGetDecvice("UserLed");
    struct IODev *ptKeyDev = IOGetDecvice("UserKey");
    ptLedDev->Write(ptLedDev, ptKeyDev->Read(ptKeyDev));
    IWDTDrvRefresh();
}

26.3.4 Test procedures

In this experiment, after initializing each peripheral, there is no need to do anything in the main loop. All operations are completed in interrupts:

  • key interrupt
  • Tick ​​timer eliminates key jitter
  • NMI interrupt handles user emergencies

The test function code is as follows:

void IWDTAppTest(void)
{
    
    
    SystickInit();
    UARTDrvInit();
    
    struct IODev *ptdev = IOGetDecvice("UserKey");
    if(NULL != ptdev)
        ptdev->Init(ptdev);
    ptdev = IOGetDecvice("UserLed");
    if(NULL != ptdev)
        ptdev->Init(ptdev);
    
    IWDTDrvInit();
    
    while(1)
    {
    
    
        /* The code that is watched by iwdt */
    }
}

26.3.5 Test results

Burn the compiled binary executable file to the board and run it. If you do not press the button, you will get the printed information as shown below:

image8


End of this chapter

Guess you like

Origin blog.csdn.net/qq_35181236/article/details/132866566