MCUXpresso_MCXA153/devices/MCXA153/drivers/fsl_cdog.c
Yilin Sun 35e678394a
Initial commit v2.14.2
Signed-off-by: Yilin Sun <imi415@imi.moe>
2024-02-11 19:33:06 +08:00

397 lines
12 KiB
C

/*
* Copyright 2020-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_cdog.h"
/*******************************************************************************
* Definitions
*******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.cdog"
#endif
/* Reset CONTROL mask */
#define RESERVED_CTRL_MASK 0x800u
#if defined(CDOG_IRQS)
/* Array of IRQs */
static const IRQn_Type s_CdogIrqs[] = CDOG_IRQS;
#endif /* CDOG_IRQS */
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
#if defined(CDOG)
/*!
* Weak implementation of CDOG IRQ, should be re-defined by user when using CDOG IRQ
*/
__WEAK void CDOG_DriverIRQHandler(void)
{
/* NVIC_DisableIRQ(CDOG_IRQn);
* CDOG_Stop(CDOG, s_start);
* CDOG->FLAGS = 0x0U;
* CDOG_Start(CDOG, 0xFFFFFFU, s_start);
* NVIC_EnableIRQ(CDOG_IRQn);
*/
}
#endif
#if defined(CDOG0)
/*!
* Weak implementation of CDOG0 IRQ, should be re-defined by user when using CDOG IRQ
*/
__WEAK void CDOG0_DriverIRQHandler(void)
{
/* NVIC_DisableIRQ(CDOG0_IRQn);
* CDOG_Stop(CDOG0, s_start);
* CDOG0->FLAGS = 0x0U;
* CDOG_Start(CDOG0, 0xFFFFFFU, s_start);
* NVIC_EnableIRQ(CDOG0_IRQn);
*/
}
#endif
#if defined(CDOG1)
/*!
* Weak implementation of CDOG1 IRQ, should be re-defined by user when using CDOG IRQ
*/
__WEAK void CDOG1_DriverIRQHandler(void)
{
/* NVIC_DisableIRQ(CDOG1_IRQn);
* CDOG_Stop(CDOG1, s_start);
* CDOG1->FLAGS = 0x0U;
* CDOG_Start(CDOG1, 0xFFFFFFU, s_start);
* NVIC_EnableIRQ(CDOG1_IRQn);
*/
}
#endif
/*!
* brief Sets the default configuration of CDOG
*
* This function initialize CDOG config structure to default values.
*
* param conf CDOG configuration structure
*/
void CDOG_GetDefaultConfig(cdog_config_t *conf)
{
/* Default configuration after reset */
conf->lock = (uint8_t)kCDOG_LockCtrl_Unlock; /* Lock control */
conf->timeout = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Timeout control */
conf->miscompare = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Miscompare control */
conf->sequence = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Sequence control */
conf->state = (uint8_t)kCDOG_FaultCtrl_NoAction; /* State control */
conf->address = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Address control */
conf->irq_pause = (uint8_t)kCDOG_IrqPauseCtrl_Run; /* IRQ pause control */
conf->debug_halt = (uint8_t)kCDOG_DebugHaltCtrl_Run; /* Debug halt control */
return;
}
/*!
* brief Sets secure counter and instruction timer values
*
* This function sets value in RELOAD and START registers for instruction timer.
*
* param base CDOG peripheral base address
* param reload reload value
* param start start value
*/
void CDOG_Start(CDOG_Type *base, uint32_t reload, uint32_t start)
{
base->RELOAD = reload;
base->START = start;
}
/*!
* brief Stops secure counter and instruction timer
*
* This function stops instruction timer and secure counter.
* This also change state of CDOG to IDLE.
*
* param base CDOG peripheral base address
* param stop expected value which will be compared with value of secure counter
*/
void CDOG_Stop(CDOG_Type *base, uint32_t stop)
{
base->STOP = stop;
}
/*!
* brief Sets secure counter and instruction timer values
*
* This function sets value in STOP, RELOAD and START registers
* for instruction timer and secure counter.
*
* param base CDOG peripheral base address
* param stop expected value which will be compared with value of secure counter
* param reload reload value for instruction timer
* param start start value for secure timer
*/
void CDOG_Set(CDOG_Type *base, uint32_t stop, uint32_t reload, uint32_t start)
{
base->STOP = stop;
base->RELOAD = reload;
base->START = start;
}
/*!
* brief Add value to secure counter
*
* This function add specified value to secure counter.
*
* param base CDOG peripheral base address.
* param add Value to be added.
*/
void CDOG_Add(CDOG_Type *base, uint32_t add)
{
base->ADD = (secure_counter_t)add;
}
/*!
* brief Add 1 to secure counter
*
* This function add 1 to secure counter.
*
* param base CDOG peripheral base address.
* param add Value to be added.
*/
void CDOG_Add1(CDOG_Type *base)
{
base->ADD1 = (secure_counter_t)0x1U;
}
/*!
* brief Add 16 to secure counter
*
* This function add 16 to secure counter.
*
* param base CDOG peripheral base address.
* param add Value to be added.
*/
void CDOG_Add16(CDOG_Type *base)
{
base->ADD16 = (secure_counter_t)0x1U;
}
/*!
* brief Add 256 to secure counter
*
* This function add 256 to secure counter.
*
* param base CDOG peripheral base address.
* param add Value to be added.
*/
void CDOG_Add256(CDOG_Type *base)
{
base->ADD256 = (secure_counter_t)0x1U;
}
/*!
* brief Substract value to secure counter
*
* This function substract specified value to secure counter.
*
* param base CDOG peripheral base address.
* param sub Value to be substracted.
*/
void CDOG_Sub(CDOG_Type *base, uint32_t sub)
{
base->SUB = (secure_counter_t)sub;
}
/*!
* brief Substract 1 from secure counter
*
* This function substract specified 1 from secure counter.
*
* param base CDOG peripheral base address.
*/
void CDOG_Sub1(CDOG_Type *base)
{
base->SUB1 = (secure_counter_t)0x1U;
}
/*!
* brief Substract 16 from secure counter
*
* This function substract specified 16 from secure counter.
*
* param base CDOG peripheral base address.
*/
void CDOG_Sub16(CDOG_Type *base)
{
base->SUB16 = (secure_counter_t)0x1U;
}
/*!
* brief Substract 256 from secure counter
*
* This function substract specified 256 from secure counter.
*
* param base CDOG peripheral base address.
*/
void CDOG_Sub256(CDOG_Type *base)
{
base->SUB256 = (secure_counter_t)0x1U;
}
/*!
* brief Checks secure counter.
*
* This function compares stop value with secure counter value
* by writting to RELOAD refister.
*
* param base CDOG peripheral base address
* param check expected (stop) value.
*/
void CDOG_Check(CDOG_Type *base, uint32_t check)
{
base->RESTART = check;
}
/*!
* brief Set the CDOG persistent word.
*
* param base CDOG peripheral base address.
* param value The value to be written.
*/
void CDOG_WritePersistent(CDOG_Type *base, uint32_t value)
{
base->PERSISTENT = value;
}
/*!
* brief Get the CDOG persistent word.
*
* param base CDOG peripheral base address.
* return The persistent word.
*/
uint32_t CDOG_ReadPersistent(CDOG_Type *base)
{
return base->PERSISTENT;
}
/*!
* brief Initialize CDOG
*
* This function initializes CDOG setting and enable all interrupts.
*
* param base CDOG peripheral base address
* param conf CDOG configuration structure
* return Status of the init operation
*/
status_t CDOG_Init(CDOG_Type *base, cdog_config_t *conf)
{
/* Ungate clock to CDOG engine and reset it */
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#ifdef CDOG_CLOCKS
CLOCK_EnableClock(kCLOCK_Cdog);
#endif /* CDOG_CLOCKS */
#endif /* !FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_CDOG_HAS_NO_RESET) && FSL_FEATURE_CDOG_HAS_NO_RESET)
RESET_PeripheralReset(kCDOG_RST_SHIFT_RSTn);
#endif /* !FSL_FEATURE_CDOG_HAS_NO_RESET */
if (base->CONTROL == 0x0U)
{
/* CDOG is not in IDLE mode, which may be cause after SW reset. */
/* Writing to CONTROL register will trigger fault. */
return kStatus_Fail;
}
/* Clear pending errors, otherwise the device will reset */
/* itself immediately after enable Code Watchdog */
if ((uint32_t)kCDOG_LockCtrl_Lock ==
((base->CONTROL & CDOG_CONTROL_LOCK_CTRL_MASK) >> CDOG_CONTROL_LOCK_CTRL_SHIFT))
{
base->FLAGS = CDOG_FLAGS_TO_FLAG(1U) | CDOG_FLAGS_MISCOM_FLAG(1U) | CDOG_FLAGS_SEQ_FLAG(1U) |
CDOG_FLAGS_CNT_FLAG(1U) | CDOG_FLAGS_STATE_FLAG(1U) | CDOG_FLAGS_ADDR_FLAG(1U) |
CDOG_FLAGS_POR_FLAG(1U);
}
else
{
/* load default values for CDOG->CONTROL before flags clear */
#if defined(FSL_FEATURE_CDOG_NEED_LOAD_DEFAULT_CONF) && (FSL_FEATURE_CDOG_NEED_LOAD_DEFAULT_CONF > 0)
cdog_config_t default_conf;
/* Initialize CDOG */
CDOG_GetDefaultConfig(&default_conf);
/* Write default value to CDOG->CONTROL*/
base->CONTROL =
CDOG_CONTROL_TIMEOUT_CTRL(default_conf.timeout) | /* Action if the timeout event is triggered */
CDOG_CONTROL_MISCOMPARE_CTRL(default_conf.miscompare) | /* Action if the miscompare error event is triggered */
CDOG_CONTROL_SEQUENCE_CTRL(default_conf.sequence) | /* Action if the sequence error event is triggered */
CDOG_CONTROL_STATE_CTRL(default_conf.state) | /* Action if the state error event is triggered */
CDOG_CONTROL_ADDRESS_CTRL(default_conf.address) | /* Action if the address error event is triggered */
CDOG_CONTROL_IRQ_PAUSE(default_conf.irq_pause) | /* Pause running during interrupts setup */
CDOG_CONTROL_DEBUG_HALT_CTRL(default_conf.debug_halt) | /* Halt CDOG timer during debug */
CDOG_CONTROL_LOCK_CTRL(default_conf.lock) | RESERVED_CTRL_MASK; /* Lock control register, RESERVED */
#endif /* FSL_FEATURE_CDOG_NEED_LOAD_DEFAULT_CONF */
base->FLAGS = CDOG_FLAGS_TO_FLAG(0U) | CDOG_FLAGS_MISCOM_FLAG(0U) | CDOG_FLAGS_SEQ_FLAG(0U) |
CDOG_FLAGS_CNT_FLAG(0U) | CDOG_FLAGS_STATE_FLAG(0U) | CDOG_FLAGS_ADDR_FLAG(0U) |
CDOG_FLAGS_POR_FLAG(0U);
}
base->CONTROL =
CDOG_CONTROL_TIMEOUT_CTRL(conf->timeout) | /* Action if the timeout event is triggered */
CDOG_CONTROL_MISCOMPARE_CTRL(conf->miscompare) | /* Action if the miscompare error event is triggered */
CDOG_CONTROL_SEQUENCE_CTRL(conf->sequence) | /* Action if the sequence error event is triggered */
CDOG_CONTROL_STATE_CTRL(conf->state) | /* Action if the state error event is triggered */
CDOG_CONTROL_ADDRESS_CTRL(conf->address) | /* Action if the address error event is triggered */
CDOG_CONTROL_IRQ_PAUSE(conf->irq_pause) | /* Pause running during interrupts setup */
CDOG_CONTROL_DEBUG_HALT_CTRL(conf->debug_halt) | /* Halt CDOG timer during debug */
CDOG_CONTROL_LOCK_CTRL(conf->lock) | RESERVED_CTRL_MASK; /* Lock control register, RESERVED */
#if defined(CDOG_IRQS)
/* Enable peripheral IRQs, if defined in array */
for (uint32_t i = 0; i < ARRAY_SIZE(s_CdogIrqs); i++)
{
NVIC_EnableIRQ(s_CdogIrqs[i]);
}
#endif /* CDOG_IRQS */
return kStatus_Success;
}
/*!
* brief Deinitialize CDOG
*
* This function stops CDOG secure counter.
*
* param base CDOG peripheral base address
*/
void CDOG_Deinit(CDOG_Type *base)
{
#if defined(CDOG_IRQS)
/* Enable peripheral IRQs, if defined in array */
for (uint32_t i = 0; i < ARRAY_SIZE(s_CdogIrqs); i++)
{
NVIC_DisableIRQ(s_CdogIrqs[i]);
}
#endif /* CDOG_IRQS */
#if !(defined(FSL_FEATURE_CDOG_HAS_NO_RESET) && FSL_FEATURE_CDOG_HAS_NO_RESET)
RESET_SetPeripheralReset(kCDOG_RST_SHIFT_RSTn);
#endif /* !FSL_FEATURE_CDOG_HAS_NO_RESET */
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#ifdef CDOG_CLOCKS
CLOCK_DisableClock(kCLOCK_Cdog);
#endif /* CDOG_CLOCKS */
#endif /* !FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}