/*******************************************************************************
 * 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 2022-2023 Renesas Electronics Corporation All rights reserved.
 *******************************************************************************/

/*******************************************************************************
 * DESCRIPTION   : window watchdog timer driver
 ******************************************************************************/
/******************************************************************************
 * @file          wdt.c
 * - Version      : 0.04
 * @brief         Window Watchdog Timer driver
 * .
 *****************************************************************************/
/******************************************************************************
 * History : DD.MM.YYYY Version  Description
 *         : 28.07.2021 0.01     First Release
 *         : 06.01.2022 0.02     Add exception handling for ICUMX_WDTA.
 *         : 20.01.2022 0.03     Add ICUMX name unification.
 *         : 11.01.2023 0.04     Modify activation code writing to
 *         :                     ICUMX_WDTA0EVAC register.
 *****************************************************************************/

#include <stdint.h>
#include <wdt.h>
#include <mem_io.h>
#include <intc.h>
#include <intc_id.h>
#include <log.h>


#define ICUMX_WDTA0_BASE    (0xFFFEE080U)   /* Watchdog Timer base */
#define ICUMX_WDTA0WDTE     (ICUMX_WDTA0_BASE)
#define ICUMX_WDTA0EVAC     (ICUMX_WDTA0_BASE+0x0004U)
#define ICUMX_WDTA0REF      (ICUMX_WDTA0_BASE+0x0008U)
#define ICUMX_WDTA0MD       (ICUMX_WDTA0_BASE+0x000CU)


#define	WDTA0MD_WDTA0WIE	(1U<<3)	 /* Enables the 75% interrupt request INTWDTA0 */
#define	WDTA0MD_WDTA0ERM	(1U<<2)	 /* 0:NMI request mode 1:Reset mode */
#define	WDTA0MD_WDTA0WS10	(3U) 	 /* 11B: window-open period is 100% */

/* overflow time setting */
#define	WDT_11MS		(0x0U)
#define	WDT_23MS		(0x1U)
#define	WDT_46MS		(0x2U)
#define	WDT_93MS		(0x3U)
#define	WDT_187MS		(0x4U)
#define	WDT_374MS		(0x5U)
#define	WDT_749MS		(0x6U)
#define	WDT_1498MS		(0x7U)

/* Activation code */
#define	WDT_ACT_CODE		(0xACU)

/* ICUMX Configuration Register */
#define ICUMX_CFG4              (0xFFFEE270U)
/* Bit definition for Configuration Register */
#define ICUMX_CFG4_ICUMOPWDVAC  (0x00000020U)

/* Initialization Window Watchdog Timer */
void wdt_init(void)
{
	uint8_t wdta_val;

	/* This API is executed before copying a part of Loader to Local RAM. */
    /* Therefore, this API can not use the Memory mapped I/O API.         */
    /* When reading or writing memory, execute the same processing as     */
    /* Memory mapped I/O API in this function.                    */
	wdta_val = WDTA0MD_WDTA0ERM; /* NMI request mode */
	wdta_val |= WDTA0MD_WDTA0WIE; /* Enables the 75% interrupt request INTWDTA0 */
	wdta_val |= WDTA0MD_WDTA0WS10;
	wdta_val |= (WDT_1498MS << 4U); /* overflow interval time */
	mem_write8(ICUMX_WDTA0MD, wdta_val);

	/* set watchdog timer handler */
	intc_set_interrupt(WDT0_INT, 7U, (INT_HANDLER)wdt_handler);

	/* watchdog timer restart */
	wdt_restart();
}
/* End of function wdt_init(uint32_t overflow_time) */

void wdt_restart(void)
{
    uint8_t  reg8;
    uint32_t reg32;

    reg32 = mem_read32(ICUMX_CFG4);

    if((reg32 & ICUMX_CFG4_ICUMOPWDVAC) != 0U)
    {
        reg8 = mem_read8(ICUMX_WDTA0REF);
        reg8 = WDT_ACT_CODE - reg8;
        /* Watchdog Timer restart.                                                                     */
        /* Subtract ICUMX_WDTA0REF from activation code when VAC(Variable Activation Code) is enabled. */
        mem_write8(ICUMX_WDTA0EVAC, reg8);
    }
    else
    {
        /* Watchdog Timer restart. */
        mem_write8(ICUMX_WDTA0EVAC,  WDT_ACT_CODE);
    }
}
/* End of function wdt_restart(void) */

/* Interrupt handling function */
void wdt_handler(void)
{
	intc_disable_interrupt(WDT0_INT);
	ERROR("\n");
	ERROR("ICUMX: System WDT overflow\n");
	panic;
}
/* End of function wdt_handler(void) */
