4
0
mirror of https://github.com/RT-Thread/rt-thread.git synced 2025-02-11 16:49:12 +08:00
2020-12-25 14:33:03 +08:00

263 lines
9.3 KiB
C

/**
*******************************************************************************
* @file hc32f4a0_swdt.c
* @brief This file provides firmware functions to manage the Special Watch Dog
* Timer(SWDT).
@verbatim
Change Logs:
Date Author Notes
2020-06-12 Yangjp First version
2020-09-04 Yangjp Optimize timeout handling in functions
@endverbatim
*******************************************************************************
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by HDSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f4a0_swdt.h"
#include "hc32f4a0_utility.h"
/**
* @addtogroup HC32F4A0_DDL_Driver
* @{
*/
/**
* @defgroup DDL_SWDT SWDT
* @brief Special Watch Dog Timer
* @{
*/
#if (DDL_SWDT_ENABLE == DDL_ON)
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/**
* @defgroup SWDT_Local_Macros SWDT Local Macros
* @{
*/
/* SWDT Registers Clear Mask */
#define SWDT_CR_CLEAR_MASK (SWDT_CR_PERI | SWDT_CR_CKS | SWDT_CR_WDPT | \
SWDT_CR_SLPOFF | SWDT_CR_ITS)
/* SWDT Refresh Key */
#define SWDT_REFRESH_KEY_START (0x0123UL)
#define SWDT_REFRESH_KEY_END (0x3210UL)
/* SWDT clear flag timeout(ms) */
#define SWDT_CLEAR_FLAG_TIMEOUT (5UL)
/**
* @defgroup SWDT_Check_Parameters_Validity SWDT Check Parameters Validity
* @{
*/
#define IS_SWDT_COUNTER_CYCLE(x) \
( ((x) == SWDT_COUNTER_CYCLE_256) || \
((x) == SWDT_COUNTER_CYCLE_4096) || \
((x) == SWDT_COUNTER_CYCLE_16384) || \
((x) == SWDT_COUNTER_CYCLE_65536))
#define IS_SWDT_CLOCK_DIVISION(x) \
( ((x) == SWDT_CLOCK_DIV1) || \
((x) == SWDT_CLOCK_DIV16) || \
((x) == SWDT_CLOCK_DIV32) || \
((x) == SWDT_CLOCK_DIV64) || \
((x) == SWDT_CLOCK_DIV128) || \
((x) == SWDT_CLOCK_DIV256) || \
((x) == SWDT_CLOCK_DIV2048))
#define IS_SWDT_ALLOW_REFRESH_RANGE(x) \
( ((x) == SWDT_RANGE_0TO100PCT) || \
((x) == SWDT_RANGE_0TO25PCT) || \
((x) == SWDT_RANGE_25TO50PCT) || \
((x) == SWDT_RANGE_0TO50PCT) || \
((x) == SWDT_RANGE_50TO75PCT) || \
((x) == SWDT_RANGE_0TO25PCT_50TO75PCT) || \
((x) == SWDT_RANGE_25TO75PCT) || \
((x) == SWDT_RANGE_0TO75PCT) || \
((x) == SWDT_RANGE_75TO100PCT) || \
((x) == SWDT_RANGE_0TO25PCT_75TO100PCT) || \
((x) == SWDT_RANGE_25TO50PCT_75TO100PCT) || \
((x) == SWDT_RANGE_0TO50PCT_75TO100PCT) || \
((x) == SWDT_RANGE_50TO100PCT) || \
((x) == SWDT_RANGE_0TO25PCT_50TO100PCT) || \
((x) == SWDT_RANGE_25TO100PCT))
#define IS_SWDT_LPM_COUNT(x) \
( ((x) == SWDT_LPM_COUNT_CONTINUE) || \
((x) == SWDT_LPM_COUNT_STOP))
#define IS_SWDT_REQUEST_TYPE(x) \
( ((x) == SWDT_TRIG_EVENT_INT) || \
((x) == SWDT_TRIG_EVENT_RESET))
#define IS_SWDT_FLAG(x) \
( (0UL != (x)) && \
(0UL == ((x) & ((uint32_t)(~(SWDT_FLAG_UDF | SWDT_FLAG_REF))))))
/**
* @}
*/
/**
* @}
*/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
* @defgroup SWDT_Global_Functions SWDT Global Functions
* @{
*/
/**
* @brief Initialize SWDT.
* @param [in] pstcSwdtInit Pointer to a @ref stc_swdt_init_t structure
* @retval An en_result_t enumeration value:
* - Ok: Initialize success
* - ErrorInvalidParameter: Invalid parameter
*/
en_result_t SWDT_Init(const stc_swdt_init_t *pstcSwdtInit)
{
en_result_t enRet = Ok;
if(NULL == pstcSwdtInit)
{
enRet = ErrorInvalidParameter;
}
else
{
/* Check parameters */
DDL_ASSERT(IS_SWDT_COUNTER_CYCLE(pstcSwdtInit->u32CountCycle));
DDL_ASSERT(IS_SWDT_CLOCK_DIVISION(pstcSwdtInit->u32ClockDivision));
DDL_ASSERT(IS_SWDT_ALLOW_REFRESH_RANGE(pstcSwdtInit->u32RefreshRange));
DDL_ASSERT(IS_SWDT_LPM_COUNT(pstcSwdtInit->u32LPModeCountEn));
DDL_ASSERT(IS_SWDT_REQUEST_TYPE(pstcSwdtInit->u32TrigType));
/* SWDT CR Configuration(Software Start Mode) */
MODIFY_REG32(M4_SWDT->CR, SWDT_CR_CLEAR_MASK,
(pstcSwdtInit->u32CountCycle | pstcSwdtInit->u32ClockDivision |
pstcSwdtInit->u32RefreshRange | pstcSwdtInit->u32LPModeCountEn |
pstcSwdtInit->u32TrigType));
}
return enRet;
}
/**
* @brief SWDT feed dog.
* @note In software startup mode, Start counter when refreshing for the first time.
* @param None
* @retval None
*/
void SWDT_Feed(void)
{
WRITE_REG32(M4_SWDT->RR, SWDT_REFRESH_KEY_START);
WRITE_REG32(M4_SWDT->RR, SWDT_REFRESH_KEY_END);
}
/**
* @brief Get SWDT flag status.
* @param [in] u32Flag Specifies the SWDT flag type.
* This parameter can be one or any combination of the following values:
* @arg SWDT_FLAG_UDF: Count Underflow flag
* @arg SWDT_FLAG_REF: Refresh Error flag
* @retval An en_flag_status_t enumeration value:
* - Set: Flag is set
* - Reset: Flag is reset
*/
en_flag_status_t SWDT_GetStatus(uint32_t u32Flag)
{
en_flag_status_t enFlagSta = Reset;
/* Check parameters */
DDL_ASSERT(IS_SWDT_FLAG(u32Flag));
if (0UL != (READ_REG32_BIT(M4_SWDT->SR, u32Flag)))
{
enFlagSta = Set;
}
return enFlagSta;
}
/**
* @brief Clear SWDT flag status.
* @param [in] u32Flag Specifies the SWDT flag type.
* This parameter can be one or any combination of the following values:
* @arg SWDT_FLAG_UDF: Count Underflow flag
* @arg SWDT_FLAG_REF: Refresh Error flag
* @retval An en_result_t enumeration value:
* - Ok: Clear flag success
* - ErrorTimeout: Clear flag timeout
*/
en_result_t SWDT_ClearStatus(uint32_t u32Flag)
{
__IO uint32_t u32Count;
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_SWDT_FLAG(u32Flag));
CLEAR_REG32_BIT(M4_SWDT->SR, u32Flag);
/* Waiting for FLAG bit clear */
u32Count = SWDT_CLEAR_FLAG_TIMEOUT * (HCLK_VALUE / 20000UL);
while (0UL != READ_REG32_BIT(M4_SWDT->SR, u32Flag))
{
if (0UL == u32Count)
{
enRet = ErrorTimeout;
break;
}
u32Count--;
}
return enRet;
}
/**
* @}
*/
#endif /* DDL_SWDT_ENABLE */
/**
* @}
*/
/**
* @}
*/
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/