lib: Add hc32f460 definitions

Signed-off-by: Steven Gotthardt <gotthardt@gmail.com>
This commit is contained in:
Steven Gotthardt
2022-12-18 15:05:51 -07:00
committed by Kevin O'Connor
parent 1e7057e917
commit 94cbf5ff48
87 changed files with 80723 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,307 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_aes.c
**
** A detailed description is available at
** @link AesGroup Aes description @endlink
**
** - 2018-10-20 CDT First version for Device Driver Library of Aes.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_aes.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup AesGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* AES block length in bytes is 16. */
#define AES_BLOCK_LEN ((uint8_t)16)
/* Each encryption operation takes 440 system clock cycles. */
#define AES_ENCRYPT_TIMEOUT (440u)
/* Each decryption operation takes 580 system clock cycles. */
#define AES_DECRYPT_TIMEOUT (580u)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
static void AES_WriteData(const uint8_t *pu8SrcData);
static void AES_ReadData(uint8_t *pu8Dest);
static void AES_WriteKey(const uint8_t *pu8Key);
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief AES128 encryption(ECB mode).
**
** \param [in] pu8Plaintext Pointer to plaintext(the source data which will be encrypted)
**
** \param [in] u32PlaintextSize Length of plaintext in bytes.
**
** \param [in] pu8Key Pointer to the AES key.
**
** \param [out] pu8Ciphertext The destination address to store the result of the encryption.
**
** \retval Ok No error occurred.
** \retval ErrorTimeout AES works timeout.
** \retval ErrorInvalidParameter Parameter error.
**
******************************************************************************/
en_result_t AES_Encrypt(const uint8_t *pu8Plaintext,
uint32_t u32PlaintextSize,
const uint8_t *pu8Key,
uint8_t *pu8Ciphertext)
{
en_result_t enRet = ErrorInvalidParameter;
uint32_t u32BlockOffset;
uint32_t u32Index;
__IO uint32_t u32TimeCount;
if ((NULL != pu8Plaintext) &&
(0u != u32PlaintextSize) &&
(NULL != pu8Key) &&
(NULL != pu8Ciphertext) &&
(0u == (u32PlaintextSize & 0xFu)) && /* u32PlaintextSize % AES_BLOCK_LEN */
(0u == ((uint32_t)pu8Plaintext & 0x3u)) && /* (uint32_t)pu8Ciphertext % 4u */
(0u == ((uint32_t)pu8Key & 0x3u)) && /* (uint32_t)pu8Key % 4u */
(0u == ((uint32_t)pu8Ciphertext & 0x3u))) /* (uint32_t)pu8Plaintext % 4u */
{
/* Write the key to the register. */
AES_WriteKey(pu8Key);
u32BlockOffset = 0u;
while (0u != u32PlaintextSize)
{
/* Stop AES calculating. */
bM4_AES_CR_START = 0u;
/* Write data. */
u32Index = u32BlockOffset * AES_BLOCK_LEN;
AES_WriteData(&pu8Plaintext[u32Index]);
/* Set AES encrypt. */
bM4_AES_CR_MODE = 0u;
/* Start AES calculating. */
bM4_AES_CR_START = 1u;
enRet = ErrorTimeout;
u32TimeCount = 0u;
while (u32TimeCount < AES_ENCRYPT_TIMEOUT)
{
if (bM4_AES_CR_START == 0u)
{
enRet = Ok;
break;
}
u32TimeCount++;
}
if (enRet == ErrorTimeout)
{
break;
}
AES_ReadData(&pu8Ciphertext[u32Index]);
u32PlaintextSize -= AES_BLOCK_LEN;
u32BlockOffset++;
}
/* Stop AES calculating. */
bM4_AES_CR_START = 0u;
}
return enRet;
}
/**
*******************************************************************************
** \brief AES128 decryption(ECB mode).
**
** \param [in] pu8Ciphertext Pointer to ciphertext(the source data which will be decrypted)
**
** \param [in] u32CiphertextSize Length of ciphertext in bytes.
**
** \param [in] pu8Key Pointer to the AES key.
**
** \param [out] pu8Plaintext The destination address to store the result of the decryption.
**
** \retval Ok No error occurred.
** \retval ErrorTimeout AES works timeout.
** \retval ErrorInvalidParameter Parameter error.
**
******************************************************************************/
en_result_t AES_Decrypt(const uint8_t *pu8Ciphertext,
uint32_t u32CiphertextSize,
const uint8_t *pu8Key,
uint8_t *pu8Plaintext)
{
en_result_t enRet = ErrorInvalidParameter;
uint32_t u32BlockOffset;
uint32_t u32Index;
__IO uint32_t u32TimeCount;
if ((NULL != pu8Ciphertext) &&
(0u != u32CiphertextSize) &&
(NULL != pu8Key) &&
(NULL != pu8Plaintext) &&
(0u == (u32CiphertextSize & 0xFu)) && /* u32CiphertextSize % AES_BLOCK_LEN */
(0u == ((uint32_t)pu8Ciphertext & 0x3u)) && /* (uint32_t)pu8Ciphertext % 4u */
(0u == ((uint32_t)pu8Key & 0x3u)) && /* (uint32_t)pu8Key % 4u */
(0u == ((uint32_t)pu8Plaintext & 0x3u))) /* (uint32_t)pu8Plaintext % 4u */
{
/* Write the key to the register. */
AES_WriteKey(pu8Key);
u32BlockOffset = 0u;
while (0u != u32CiphertextSize)
{
/* Stop AES calculating. */
bM4_AES_CR_START = 0u;
/* Write data. */
u32Index = u32BlockOffset * AES_BLOCK_LEN;
AES_WriteData(&pu8Ciphertext[u32Index]);
/* Set AES decrypt. */
bM4_AES_CR_MODE = 1u;
/* Start AES calculating. */
bM4_AES_CR_START = 1u;
enRet = ErrorTimeout;
u32TimeCount = 0u;
while (u32TimeCount < AES_DECRYPT_TIMEOUT)
{
if (bM4_AES_CR_START == 0u)
{
enRet = Ok;
break;
}
u32TimeCount++;
}
if (enRet == ErrorTimeout)
{
break;
}
AES_ReadData(&pu8Plaintext[u32Index]);
u32CiphertextSize -= AES_BLOCK_LEN;
u32BlockOffset++;
}
/* Stop AES calculating. */
bM4_AES_CR_START = 0u;
}
return enRet;
}
/*******************************************************************************
* Function implementation - local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Writes the input buffer in data register.
**
** \param [in] pu8SrcData Pointer to source data buffer.
**
** \retval None.
**
******************************************************************************/
static void AES_WriteData(const uint8_t *pu8SrcData)
{
uint8_t i;
uint32_t u32SrcAddr = (uint32_t)pu8SrcData;
uint32_t u32DrAddr = (uint32_t)&(M4_AES->DR0);
for (i = 0u; i < 4u; i++)
{
*(__IO uint32_t *)u32DrAddr = *(uint32_t*)u32SrcAddr;
u32SrcAddr += 4u;
u32DrAddr += 4u;
}
}
/**
*******************************************************************************
** \brief Reads the from data register.
**
** \param [out] pu8Dest Pointer to the destination buffer.
**
** \retval None.
**
******************************************************************************/
static void AES_ReadData(uint8_t *pu8Dest)
{
uint8_t i;
uint32_t u32DestAddr = (uint32_t)pu8Dest;
uint32_t u32DrAddr = (uint32_t)&(M4_AES->DR0);
for (i = 0u; i < 4u; i++)
{
*(uint32_t*)u32DestAddr = *(__IO uint32_t *)u32DrAddr;
u32DestAddr += 4u;
u32DrAddr += 4u;
}
}
/**
*******************************************************************************
** \brief Writes the input buffer in key register.
**
** \param [in] pu8Key Pointer to AES key.
**
** \retval None.
**
******************************************************************************/
static void AES_WriteKey(const uint8_t *pu8Key)
{
uint8_t i;
uint32_t u32SrcKeyAddr = (uint32_t)pu8Key;
uint32_t u32KeyAddr = (uint32_t)&(M4_AES->KR0);
for (i = 0u; i < 4u; i++)
{
*(__IO uint32_t *)u32KeyAddr = *(uint32_t*)u32SrcKeyAddr;
u32SrcKeyAddr += 4u;
u32KeyAddr += 4u;
}
}
//@} // AesGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,558 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_can.c
**
** A detailed description is available at
** @link CanGroup CAN description @endlink
**
** - 2018-12-13 CDT First version for Device Driver Library of CAN.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_can.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup CanGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define CAN_RESET_ENABLE() (M4_CAN->CFG_STAT_f.RESET = 1u)
#define CAN_RESET_DISABLE() \
do{ \
do{ \
M4_CAN->CFG_STAT_f.RESET = 0u; \
}while(M4_CAN->CFG_STAT_f.RESET); \
}while(0)
#define CAN_RW_MEM32(addr) (*(__IO uint32_t *)(addr))
#define CAN_ACF_ID_REG_SEL ((uint8_t)0x00u)
#define CAN_ACF_MASK_REG_SEL ((uint8_t)0x01u)
/*! Parameter validity check for CAN Mode \a CanMode. */
#define IS_CAN_MODE_VALID(CanMode) \
( (CanExternalLoopBackMode == (CanMode)) || \
(CanInternalLoopBackMode == (CanMode)) || \
(CanTxSignalPrimaryMode == (CanMode)) || \
(CanTxSignalSecondaryMode == (CanMode)) || \
(CanListenOnlyMode == (CanMode)) \
)
/*! Parameter validity check for CAN Tx Cmd \a TxCmd. */
#define IS_TX_CMD_VALID(TxCmd) \
( (CanPTBTxCmd == (TxCmd)) || \
(CanPTBTxAbortCmd == (TxCmd)) || \
(CanSTBTxOneCmd == (TxCmd)) || \
(CanSTBTxAllCmd == (TxCmd)) || \
(CanSTBTxAbortCmd == (TxCmd)) \
)
/*! Parameter validity check for CAN status \a enCanStatus. */
#define IS_CAN_STATUS_VALID(enCanStatus) \
( (CanRxActive == (enCanStatus)) || \
(CanTxActive == (enCanStatus)) || \
(CanBusoff == (enCanStatus)) \
)
/*! Parameter validity check for CAN Irq type \a enCanIrqType. */
#define IS_CAN_IRQ_TYPE_VALID(enCanIrqType) \
( (CanRxIrqEn == (enCanIrqType)) || \
(CanRxOverIrqEn == (enCanIrqType)) || \
(CanRxBufFullIrqEn == (enCanIrqType)) || \
(CanRxBufAlmostFullIrqEn == (enCanIrqType)) || \
(CanTxPrimaryIrqEn == (enCanIrqType)) || \
(CanTxSecondaryIrqEn == (enCanIrqType)) || \
(CanErrorIrqEn == (enCanIrqType)) || \
(CanErrorPassiveIrqEn == (enCanIrqType)) || \
(CanArbiLostIrqEn == (enCanIrqType)) || \
(CanBusErrorIrqEn == (enCanIrqType)) \
)
/*! Parameter validity check for CAN Irq flag type \a enCanIrqFLg. */
#define IS_CAN_IRQ_FLAG_VALID(enCanIrqFLg) \
( (CanTxBufFullIrqFlg == (enCanIrqFLg)) || \
(CanRxIrqFlg == (enCanIrqFLg)) || \
(CanRxOverIrqFlg == (enCanIrqFLg)) || \
(CanRxBufFullIrqFlg == (enCanIrqFLg)) || \
(CanRxBufAlmostFullIrqFlg == (enCanIrqFLg)) || \
(CanTxPrimaryIrqFlg == (enCanIrqFLg)) || \
(CanTxSecondaryIrqFlg == (enCanIrqFLg)) || \
(CanErrorIrqFlg == (enCanIrqFLg)) || \
(CanAbortIrqFlg == (enCanIrqFLg)) || \
(CanErrorWarningIrqFlg == (enCanIrqFLg)) || \
(CanErrorPassivenodeIrqFlg == (enCanIrqFLg)) || \
(CanErrorPassiveIrqFlg == (enCanIrqFLg)) || \
(CanArbiLostIrqFlg == (enCanIrqFLg)) || \
(CanBusErrorIrqFlg == (enCanIrqFLg)) \
)
/*! Parameter validity check for CAN filter \a enCanFilter. */
#define IS_CAN_FILTER_VALID(enCanFilter) \
( (enCanFilter) <= CanFilterSel8)
/*! Parameter validity check for CAN filter count \a u8Count. */
#define IS_CAN_FILTER_COUNT_VALID(u8Count) \
( (u8Count) <= 8u)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Configures the can base functions
**
** \param [in] pstcCanInitCfg The can initial config struct.
**
** \retval None
**
** \note None
**
******************************************************************************/
void CAN_Init(const stc_can_init_config_t *pstcCanInitCfg)
{
uint8_t i;
if (NULL != pstcCanInitCfg)
{
DDL_ASSERT(IS_CAN_FILTER_COUNT_VALID(pstcCanInitCfg->u8FilterCount));
CAN_RESET_ENABLE();
M4_CAN->BT_f.PRESC = pstcCanInitCfg->stcCanBt.PRESC;
M4_CAN->BT_f.SEG_1 = pstcCanInitCfg->stcCanBt.SEG_1;
M4_CAN->BT_f.SEG_2 = pstcCanInitCfg->stcCanBt.SEG_2;
M4_CAN->BT_f.SJW = pstcCanInitCfg->stcCanBt.SJW;
M4_CAN->TCTRL_f.TSMODE = pstcCanInitCfg->enCanSTBMode;
CAN_FilterConfig(pstcCanInitCfg->pstcFilter, pstcCanInitCfg->u8FilterCount);
CAN_RESET_DISABLE();
M4_CAN->RCTRL_f.RBALL = pstcCanInitCfg->enCanRxBufAll;
M4_CAN->RCTRL_f.ROM = pstcCanInitCfg->enCanRxBufMode;
M4_CAN->RCTRL_f.SACK = pstcCanInitCfg->enCanSAck;
M4_CAN->LIMIT_f.AFWL = pstcCanInitCfg->stcWarningLimit.CanWarningLimitVal;
M4_CAN->LIMIT_f.EWL = pstcCanInitCfg->stcWarningLimit.CanErrorWarningLimitVal;
// Enable filters.
for (i=0u; i<pstcCanInitCfg->u8FilterCount; i++)
{
CAN_FilterCmd(pstcCanInitCfg->pstcFilter[i].enFilterSel, Enable);
}
}
}
/**
*******************************************************************************
** \brief De-Init (RESET CAN register)
**
** \param None
**
** \retval None
**
** \note None
**
******************************************************************************/
void CAN_DeInit(void)
{
CAN_RESET_ENABLE();
}
/**
*******************************************************************************
** \brief Configures the can Mode
**
** \param [in] enMode The can mode enum. @ref en_can_mode_t
** \param [in] enNewState The new state of the can filter chanel.
** \arg Enable Enable filter.
** \arg Disable Disable filter.
** \retval None
**
** \note None
**
******************************************************************************/
void CAN_ModeConfig(en_can_mode_t enMode, en_functional_state_t enNewState)
{
DDL_ASSERT(IS_CAN_MODE_VALID(enMode));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
if(CanListenOnlyMode == enMode)
{
M4_CAN->TCMD_f.LOM = enNewState;
}else
{
if(Enable == enNewState)
{
M4_CAN->CFG_STAT |= enMode;
}else
{
M4_CAN->CFG_STAT &= ~enMode;
}
}
}
/**
*******************************************************************************
** \brief Configures the can acceptance filter
**
** \param [in] pstcFilter Pointer to a stc_can_filter_t type array.
** @ref stc_can_filter_t
** \param [in] u8FilterCount Number of filters that to be configured.
**
** \retval None
**
** \note None
**
******************************************************************************/
void CAN_FilterConfig(const stc_can_filter_t pstcFilter[], uint8_t u8FilterCount)
{
uint8_t i;
if(NULL != pstcFilter)
{
DDL_ASSERT(IS_CAN_FILTER_COUNT_VALID(u8FilterCount));
for (i=0u; i<u8FilterCount; i++)
{
DDL_ASSERT(IS_CAN_FILTER_VALID(pstcFilter[i].enFilterSel));
//<<Acceptance filter address
M4_CAN->ACFCTRL_f.ACFADR = pstcFilter[i].enFilterSel;
//<<ID config
M4_CAN->ACFCTRL_f.SELMASK = CAN_ACF_ID_REG_SEL;
M4_CAN->ACF = pstcFilter[i].u32CODE;
//<<MASK config
M4_CAN->ACFCTRL_f.SELMASK = CAN_ACF_MASK_REG_SEL;
M4_CAN->ACF = pstcFilter[i].u32MASK;
//<<Frame format config
M4_CAN->ACF_f.AIDEE = ((pstcFilter[i].enAcfFormat >> 1ul) & 0x01u);
M4_CAN->ACF_f.AIDE = (pstcFilter[i].enAcfFormat & 0x01ul);
}
}
}
/**
*******************************************************************************
** \brief Enable or disable the specified can acceptance filter.
**
** \param [in] enFilter Specifies a filter.
** @ref en_can_filter_sel_t
** \param [in] enNewState The new state of the specified filter.
** \arg Enable Enable.
** \arg Disable Disable.
**
** \retval None
**
** \note None
**
******************************************************************************/
void CAN_FilterCmd(en_can_filter_sel_t enFilter, en_functional_state_t enNewState)
{
uint8_t u8FilterSel;
DDL_ASSERT(IS_CAN_FILTER_VALID(enFilter));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
u8FilterSel = (uint8_t)(1ul << enFilter);
if(Enable == enNewState)
{
M4_CAN->ACFEN |= u8FilterSel;
}else
{
M4_CAN->ACFEN &= (uint8_t)(~u8FilterSel);
}
}
/**
*******************************************************************************
** \brief Configures the can Tx frame set
**
** \param [in] pstcTxFrame The can Tx frame struct.
** @ref stc_can_txframe_t
** \retval None
**
** \note None
**
******************************************************************************/
void CAN_SetFrame(stc_can_txframe_t *pstcTxFrame)
{
uint32_t u32TBUFAddr;
if(NULL != pstcTxFrame)
{
u32TBUFAddr = (uint32_t)&M4_CAN->TBUF;
M4_CAN->TCMD_f.TBSEL = pstcTxFrame->enBufferSel;
CAN_RW_MEM32(u32TBUFAddr) = pstcTxFrame->TBUF32_0;
CAN_RW_MEM32(u32TBUFAddr+4) = pstcTxFrame->TBUF32_1;
CAN_RW_MEM32(u32TBUFAddr+8) = pstcTxFrame->TBUF32_2[0];
CAN_RW_MEM32(u32TBUFAddr+12) = pstcTxFrame->TBUF32_2[1];
if(CanSTBSel == pstcTxFrame->enBufferSel)
{
M4_CAN->TCTRL_f.TSNEXT = Enable;
}
}
}
/**
*******************************************************************************
** \brief Configures the can Tx Command
**
** \param [in] enTxCmd The can Tx Command.
**
** \retval Can Tx buffer status @ref en_can_tx_buf_status_t
**
** \note None
**
******************************************************************************/
en_can_tx_buf_status_t CAN_TransmitCmd(en_can_tx_cmd_t enTxCmd)
{
DDL_ASSERT(IS_TX_CMD_VALID(enTxCmd));
M4_CAN->TCMD |= enTxCmd;
return (en_can_tx_buf_status_t)M4_CAN->TCTRL_f.TSSTAT;
}
/**
*******************************************************************************
** \brief Configures the can Rx frame
**
** \param [in] pstcRxFrame The can Rx frame.
** @ref stc_can_rxframe_t
** \retval Can rx buffer status @ref en_can_rx_buf_status_t
**
** \note None
**
******************************************************************************/
en_can_rx_buf_status_t CAN_Receive(stc_can_rxframe_t *pstcRxFrame)
{
uint32_t u32RBUFAddr;
if(NULL != pstcRxFrame)
{
u32RBUFAddr = (uint32_t)&M4_CAN->RBUF;
pstcRxFrame->RBUF32_0 = CAN_RW_MEM32(u32RBUFAddr);
pstcRxFrame->RBUF32_1 = CAN_RW_MEM32(u32RBUFAddr+4);
pstcRxFrame->RBUF32_2[0] = CAN_RW_MEM32(u32RBUFAddr+8);
pstcRxFrame->RBUF32_2[1] = CAN_RW_MEM32(u32RBUFAddr+12);
M4_CAN->RCTRL_f.RREL = 1u;
}
return (en_can_rx_buf_status_t)M4_CAN->RCTRL_f.RSTAT;
}
/**
*******************************************************************************
** \brief Get the can Error Status
**
** \param None
**
** \retval en_can_error_t The can error status
**
** \note None
**
******************************************************************************/
en_can_error_t CAN_ErrorStatusGet(void)
{
en_can_error_t enRet = UNKOWN_ERROR;
if(6u > M4_CAN->EALCAP_f.KOER)
{
enRet = (en_can_error_t)M4_CAN->EALCAP_f.KOER;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get the can Status
**
** \param enCanStatus The can status
** \arg true
** \arg false
** \retval bool
**
** \note None
**
******************************************************************************/
bool CAN_StatusGet(en_can_status_t enCanStatus)
{
bool bRet = false;
DDL_ASSERT(IS_CAN_STATUS_VALID(enCanStatus));
if(M4_CAN->CFG_STAT & enCanStatus)
{
bRet = true;
}
return bRet;
}
/**
*******************************************************************************
** \brief Configures the can Interrupt enable
**
** \param [in] enCanIrqType The can interrupt type.
** \param [in] enNewState The new state of the can interrupt.
** \arg Enable Enable.
** \arg Disable Disable.
**
** \retval None
**
** \note None
**
******************************************************************************/
void CAN_IrqCmd(en_can_irq_type_t enCanIrqType, en_functional_state_t enNewState)
{
volatile uint32_t *u32pIE;
DDL_ASSERT(IS_CAN_IRQ_TYPE_VALID(enCanIrqType));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
u32pIE = (volatile uint32_t*)(&M4_CAN->RTIE);
if(Enable == enNewState)
{
*u32pIE |= enCanIrqType;
}else
{
*u32pIE &= ~((uint32_t)enCanIrqType);
}
}
/**
*******************************************************************************
** \brief Get the can Interrupt Flag
**
** \param [in] enCanIrqFlgType The can interrupt Flag.
**
** \retval bool
**
** \note None
**
******************************************************************************/
bool CAN_IrqFlgGet(en_can_irq_flag_type_t enCanIrqFlgType)
{
volatile uint32_t *u32pIE = NULL;
bool bRet = false;
DDL_ASSERT(IS_CAN_IRQ_FLAG_VALID(enCanIrqFlgType));
u32pIE = (volatile uint32_t*)(&M4_CAN->RTIE);
if( *u32pIE & enCanIrqFlgType)
{
bRet = true;
}
return bRet;
}
/**
*******************************************************************************
** \brief Clear the can Interrupt Flag
**
** \param [in] enCanIrqFlgType The can interrupt type.
**
** \retval None
**
** \note None
**
******************************************************************************/
void CAN_IrqFlgClr(en_can_irq_flag_type_t enCanIrqFlgType)
{
volatile uint32_t *u32pIE = NULL;
uint32_t u32IETempMsk = 0xFF2A00FF;
DDL_ASSERT(IS_CAN_IRQ_FLAG_VALID(enCanIrqFlgType));
u32pIE = (volatile uint32_t*)(&M4_CAN->RTIE);
*u32pIE = (((*u32pIE)&u32IETempMsk) | (uint32_t)enCanIrqFlgType);
}
/**
*******************************************************************************
** \brief Get the can Rx Error Counter
**
** \param None
**
** \retval Error Counter(0~255)
**
** \note None
**
******************************************************************************/
uint8_t CAN_RxErrorCntGet(void)
{
return M4_CAN->RECNT;
}
/**
*******************************************************************************
** \brief Get the can Tx Error Counter
**
** \param None
**
** \retval Error Counter(0~255)
**
** \note None
**
******************************************************************************/
uint8_t CAN_TxErrorCntGet(void)
{
return M4_CAN->TECNT;
}
/**
*******************************************************************************
** \brief Get the can Arbitration lost captrue
**
** \param None
**
** \retval address(0~31)
**
** \note None
**
******************************************************************************/
uint8_t CAN_ArbitrationLostCap(void)
{
return M4_CAN->EALCAP_f.ALC;
}
//@} // CanGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,323 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_crc.c
**
** A detailed description is available at
** @link CrcGroup Crc description @endlink
**
** - 2019-03-07 CDT First version for Device Driver Library of Crc.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_crc.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup CrcGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* Definition of CRC16 data register. */
#define M4_CRC16_DAT (*((__IO uint16_t *)&M4_CRC->DAT0))
/* Definition of CRC16 checksum register. */
#define M4_CRC16_RSLT (*((__IO uint16_t *)&M4_CRC->RESLT))
/* Definition of CRC16 initial value register. */
#define M4_CRC16_INIT (M4_CRC16_RSLT)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
static uint32_t CRC_ProcChecksum(uint32_t u32Checksum);
static uint32_t CRC_ReverseBits(uint32_t u32Data);
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initialize the CRC.
**
** \param [in] u32Config Bit[1]: CRC_SEL_16B or CRC_SEL_32B.
** Bit[2]: CRC_REFIN_DISABLE or CRC_REFIN_ENABLE.
** Bit[3]: CRC_REFOUT_DISABLE or CRC_REFOUT_ENABLE.
** Bit[4]: CRC_XOROUT_DISABLE or CRC_XOROUT_ENABLE.
** See the definitions for details.
**
** \retval None
**
******************************************************************************/
void CRC_Init(uint32_t u32Config)
{
u32Config &= CRC_CONFIG_MASK;
M4_CRC->CR = u32Config;
}
/**
*******************************************************************************
** \brief CRC16 calculation.
**
** \param [in] u16InitVal Initial value of CRC16.
**
** \param [in] pu16Data Pointer to the buffer containing the data to be computed.
**
** \param [in] u32Length Length of the buffer to be computed.
**
** \retval 16-bit CRC checksum.
**
******************************************************************************/
uint16_t CRC_Calculate16B(uint16_t u16InitVal, const uint16_t *pu16Data, uint32_t u32Length)
{
uint16_t u16Ret = 0u;
uint32_t u32Count;
if (NULL != pu16Data)
{
M4_CRC16_INIT = u16InitVal;
for (u32Count = 0u; u32Count < u32Length; u32Count++)
{
M4_CRC16_DAT = pu16Data[u32Count];
}
u16Ret = M4_CRC16_RSLT;
}
return u16Ret;
}
/**
*******************************************************************************
** \brief CRC32 calculation.
**
** \param [in] u32InitVal Initial value of CRC32.
**
** \param [in] pu32Data Pointer to the buffer containing the data to be computed.
**
** \param [in] u32Length Length of the buffer to be computed.
**
** \retval 32-bit CRC checksum.
**
******************************************************************************/
uint32_t CRC_Calculate32B(uint32_t u32InitVal, const uint32_t *pu32Data, uint32_t u32Length)
{
uint32_t u32Ret = 0u;
uint32_t u32Count;
M4_CRC->RESLT = u32InitVal;
if (NULL != pu32Data)
{
for (u32Count = 0u; u32Count < u32Length; u32Count++)
{
M4_CRC->DAT0 = pu32Data[u32Count];
}
u32Ret = M4_CRC->RESLT;
}
return u32Ret;
}
/**
*******************************************************************************
** \brief CRC16 check.
**
** \param [in] u16InitVal Initial value of CRC16.
**
** \param [in] u16Checksum CRC16 checksum of the source data.
**
** \param [in] pu16Data Pointer to the buffer containing the data to be checked.
**
** \param [in] u32Length Length of the buffer to be checked.
**
** \retval true CRC16 checks successfully.
** \retval false CRC16 checks unsuccessfully.
**
******************************************************************************/
bool CRC_Check16B(uint16_t u16InitVal, uint16_t u16Checksum, const uint16_t *pu16Data, uint32_t u32Length)
{
bool bRet = false;
uint32_t u32Count;
uint16_t u16CrcChecksum;
if (NULL != pu16Data)
{
u16CrcChecksum = (uint16_t)CRC_ProcChecksum((uint32_t)u16Checksum);
M4_CRC16_INIT = u16InitVal;
for (u32Count = 0u; u32Count < u32Length; u32Count++)
{
M4_CRC16_DAT = pu16Data[u32Count];
}
M4_CRC16_DAT = u16CrcChecksum;
if (bM4_CRC_RESLT_CRCFLAG_16)
{
bRet = true;
}
}
return bRet;
}
/**
*******************************************************************************
** \brief CRC32 check.
**
** \param [in] u32InitVal Initial value of CRC32.
**
** \param [in] u32Checksum CRC32 checksum of the source data.
**
** \param [in] pu32Data Pointer to the buffer containing the data to be checked.
**
** \param [in] u32Length Length of the buffer to be checked.
**
** \retval true CRC32 checks successfully.
** \retval false CRC32 checks unsuccessfully.
**
******************************************************************************/
bool CRC_Check32B(uint32_t u32InitVal, uint32_t u32Checksum, const uint32_t *pu32Data, uint32_t u32Length)
{
bool bRet = false;
uint32_t u32Count;
uint32_t u32CrcChecksum;
if (NULL != pu32Data)
{
u32CrcChecksum = CRC_ProcChecksum(u32Checksum);
M4_CRC->RESLT = u32InitVal;
for (u32Count = 0u; u32Count < u32Length; u32Count++)
{
M4_CRC->DAT0 = pu32Data[u32Count];
}
M4_CRC->DAT0 = u32CrcChecksum;
if (bM4_CRC_FLG_FLAG)
{
bRet = true;
}
}
return bRet;
}
/*******************************************************************************
* Function implementation - local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Processes the checksum of CRC.
**
** \param [in] u32Checksum The checksum of CRC16 or CRC32.
**
** \retval 32-bit new checksum will be used by CRC checking.
**
******************************************************************************/
static uint32_t CRC_ProcChecksum(uint32_t u32Checksum)
{
uint8_t i;
uint8_t u8Size = 16u;
uint8_t u8Offset;
uint32_t u32Config;
uint32_t u32FinalChecksum;
uint32_t u32Temp;
u32Config = M4_CRC->CR;
u32FinalChecksum = u32Checksum;
if ((u32Config & CRC_SEL_32B) == CRC_SEL_32B)
{
u8Size = 32u;
}
if ((u32Config & CRC_REFOUT_ENABLE) == CRC_REFOUT_DISABLE)
{
/* Bits reversing. */
u32FinalChecksum = CRC_ReverseBits(u32Checksum);
if (u8Size == 16u)
{
u32FinalChecksum >>= 16u;
u32FinalChecksum &= 0xFFFFu;
}
}
if ((u32Config & CRC_XOROUT_ENABLE) == CRC_XOROUT_DISABLE)
{
/* Bits NOT. */
u32FinalChecksum = ~u32FinalChecksum;
}
if ((u32Config & CRC_REFIN_ENABLE) == CRC_REFIN_DISABLE)
{
u8Size /= 8u;
/* Bits reversing in bytes. */
for (i = 0u; i < u8Size; i++)
{
u8Offset = i * 8u;
u32Temp = (u32FinalChecksum >> u8Offset) & 0xFFul;
u32Temp = CRC_ReverseBits(u32Temp);
u32Temp = u32Temp >> (24u - u8Offset);
u32FinalChecksum &= ~((uint32_t)0xFF << u8Offset);
u32FinalChecksum |= u32Temp;
}
}
return u32FinalChecksum;
}
/**
*******************************************************************************
** \brief Reverse bits.
**
** \param [in] u32Data The data to be reversed bits.
**
** \retval 32-bit new data.
**
******************************************************************************/
static uint32_t CRC_ReverseBits(uint32_t u32Data)
{
u32Data = (((u32Data & 0xAAAAAAAAul) >> 1u) | ((u32Data & 0x55555555ul) << 1u));
u32Data = (((u32Data & 0xCCCCCCCCul) >> 2u) | ((u32Data & 0x33333333ul) << 2u));
u32Data = (((u32Data & 0xF0F0F0F0ul) >> 4u) | ((u32Data & 0x0F0F0F0Ful) << 4u));
u32Data = (((u32Data & 0xFF00FF00ul) >> 8u) | ((u32Data & 0x00FF00FFul) << 8u));
return ((u32Data >> 16u) | (u32Data << 16u));
}
//@} // CrcGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,971 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_dcu.c
**
** A detailed description is available at
** @link DcuGroup DCU description @endlink
**
** - 2018-10-15 CDT First version for Device Driver Library of DCU.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_dcu.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup DcuGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter valid check for DCU Instances. */
#define IS_VALID_DCU(__DCUx__) \
( (M4_DCU1 == (__DCUx__)) || \
(M4_DCU2 == (__DCUx__)) || \
(M4_DCU3 == (__DCUx__)) || \
(M4_DCU4 == (__DCUx__)))
/*!< Parameter valid check for DCU DATA register. */
#define IS_VALID_DCU_DATA_REG(x) \
( (DcuRegisterData0 == (x)) || \
(DcuRegisterData1 == (x)) || \
(DcuRegisterData2 == (x)))
/*!< Parameter valid check for DCU operation mode. */
#define IS_VALID_DCU_OPERATION(x) \
( (DcuOpAdd == (x)) || \
(DcuOpSub == (x)) || \
(DcuInvalid == (x)) || \
(DcuOpCompare == (x)) || \
(DcuHwTrigOpAdd == (x)) || \
(DcuHwTrigOpSub == (x)))
/*!< Parameter valid check for DCU data size. */
#define IS_VALID_DCU_DATAZ_SIZE(x) \
( (DcuDataBit8 == (x)) || \
(DcuDataBit16 == (x)) || \
(DcuDataBit32 == (x)))
/*!< Parameter valid check for DCU compare trigger mode type. */
#define IS_VALID_DCU_CMP_TRIG_MODE(x) \
( (DcuCmpTrigbyData0 == (x)) || \
(DcuCmpTrigbyData012 == (x)))
/*!< Parameter valid check for DCU interrupt. */
#define IS_VALID_DCU_INT(x) \
( (DcuIntOp == (x)) || \
(DcuIntLs2 == (x)) || \
(DcuIntEq2 == (x)) || \
(DcuIntGt2 == (x)) || \
(DcuIntLs1 == (x)) || \
(DcuIntEq1 == (x)) || \
(DcuIntGt1 == (x)))
/*!< Parameter valid check for DCU interrupt mode. */
#define IS_VALID_DCU_INT_WIN_MODE(x) \
( (DcuIntInvalid == (x)) || \
(DcuWinIntInvalid == (x)) || \
(DcuInsideWinCmpInt == (x)) || \
(DcuOutsideWinCmpInt == (x)))
/*!< Parameter valid check for external trigger event. */
#define IS_VALID_TRG_SRC_EVENT(x) \
( (((x) >= EVT_PORT_EIRQ0) && ((x) <= EVT_PORT_EIRQ15)) || \
(((x) >= EVT_DMA1_TC0) && ((x) <= EVT_DMA2_BTC3)) || \
(((x) >= EVT_EFM_OPTEND) && ((x) <= EVT_USBFS_SOF)) || \
(((x) >= EVT_DCU1) && ((x) <= EVT_DCU4)) || \
(((x) >= EVT_TMR01_GCMA) && ((x) <= EVT_TMR02_GCMB)) || \
(((x) >= EVT_RTC_ALM) && ((x) <= EVT_RTC_PRD)) || \
(((x) >= EVT_TMR61_GCMA) && ((x) <= EVT_TMR61_GUDF)) || \
(((x) >= EVT_TMR61_SCMA) && ((x) <= EVT_TMR61_SCMB)) || \
(((x) >= EVT_TMR62_GCMA) && ((x) <= EVT_TMR62_GUDF)) || \
(((x) >= EVT_TMR62_SCMA) && ((x) <= EVT_TMR62_SCMB)) || \
(((x) >= EVT_TMR63_GCMA) && ((x) <= EVT_TMR63_GUDF)) || \
(((x) >= EVT_TMR63_SCMA) && ((x) <= EVT_TMR63_SCMB)) || \
(((x) >= EVT_TMRA1_OVF) && ((x) <= EVT_TMRA5_CMP)) || \
(((x) >= EVT_TMRA6_OVF) && ((x) <= EVT_TMRA6_CMP)) || \
(((x) >= EVT_USART1_EI) && ((x) <= EVT_USART4_RTO)) || \
(((x) >= EVT_SPI1_SPRI) && ((x) <= EVT_AOS_STRG)) || \
(((x) >= EVT_TMR41_SCMUH) && ((x) <= EVT_TMR42_SCMWL)) || \
(((x) >= EVT_TMR43_SCMUH) && ((x) <= EVT_TMR43_SCMWL)) || \
(((x) >= EVT_EVENT_PORT1) && ((x) <= EVT_EVENT_PORT4)) || \
(((x) >= EVT_I2S1_TXIRQOUT) && ((x) <= EVT_I2S1_RXIRQOUT)) || \
(((x) >= EVT_I2S2_TXIRQOUT) && ((x) <= EVT_I2S2_RXIRQOUT)) || \
(((x) >= EVT_I2S3_TXIRQOUT) && ((x) <= EVT_I2S3_RXIRQOUT)) || \
(((x) >= EVT_I2S4_TXIRQOUT) && ((x) <= EVT_I2S4_RXIRQOUT)) || \
(((x) >= EVT_ACMP1) && ((x) <= EVT_ACMP3)) || \
(((x) >= EVT_I2C1_RXI) && ((x) <= EVT_I2C3_EEI)) || \
(((x) >= EVT_PVD_PVD1) && ((x) <= EVT_OTS)) || \
((x) == EVT_WDT_REFUDF) || \
(((x) >= EVT_ADC1_EOCA) && ((x) <= EVT_TRNG_END)) || \
(((x) >= EVT_SDIOC1_DMAR) && ((x) <= EVT_SDIOC1_DMAW)) || \
(((x) >= EVT_SDIOC2_DMAR) && ((x) <= EVT_SDIOC2_DMAW)) || \
((x) == EVT_MAX))
/*! Parameter valid check for DCU common trigger. */
#define IS_DCU_COM_TRIGGER(x) \
( ((x) == DcuComTrigger_1) || \
((x) == DcuComTrigger_2) || \
((x) == DcuComTrigger_1_2))
/*!< Get the specified DATA register address of the specified DCU unit */
#define DCU_DATAx(__DCUx__, __DATAx__) ((uint32_t)(&(__DCUx__)->DATA0) + ((uint32_t)(__DATAx__)) * 4u)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
static __IO uint32_t* DCU_TRGSELx(const M4_DCU_TypeDef *DCUx);
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initializes a DCU.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] pstcInitCfg Pointer to DCU configure structure
** \arg This parameter detail refer @ref stc_dcu_init_t
**
** \retval Ok DCU is initialized normally
** \retval ErrorInvalidParameter If one of following cases matches:
** - DCUx is invalid
** - pstcInitCfg == NULL
** - Other invalid configuration
**
******************************************************************************/
en_result_t DCU_Init(M4_DCU_TypeDef *DCUx, const stc_dcu_init_t *pstcInitCfg)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx && pstcInitCfg pointer */
if ((IS_VALID_DCU(DCUx)) && (NULL != pstcInitCfg))
{
/* Check the parameters */
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enIntCmd));
DDL_ASSERT(IS_VALID_DCU_OPERATION(pstcInitCfg->enOperation));
DDL_ASSERT(IS_VALID_DCU_DATAZ_SIZE(pstcInitCfg->enDataSize));
DDL_ASSERT(IS_VALID_DCU_INT_WIN_MODE(pstcInitCfg->enIntWinMode));
DDL_ASSERT(IS_VALID_DCU_CMP_TRIG_MODE(pstcInitCfg->enCmpTriggerMode));
/* De-initialize dcu register value */
DCUx->CTL = 0ul;
DCUx->INTSEL = 0ul;
DCUx->FLAGCLR = 0x7Ful;
/* Set dcu operation mode */
DCUx->CTL_f.MODE = (uint32_t)pstcInitCfg->enOperation;
/* Set dcu data sieze */
DCUx->CTL_f.DATASIZE = (uint32_t)pstcInitCfg->enDataSize;
/* Set dcu compare trigger mode */
DCUx->CTL_f.COMP_TRG = (uint32_t)pstcInitCfg->enCmpTriggerMode;
/* Set dcu interrupt window mode */
DCUx->INTSEL_f.INT_WIN = (uint32_t)pstcInitCfg->enIntWinMode;
DCUx->INTSEL = pstcInitCfg->u32IntSel;
DCUx->CTL_f.INTEN = (uint32_t)(pstcInitCfg->enIntCmd);
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief De-Initializes a DCU.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
**
** \retval Ok De-Initialized successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_DeInit(M4_DCU_TypeDef *DCUx)
{
en_result_t enRet = ErrorInvalidParameter;
__IO uint32_t *TRGSELx = DCU_TRGSELx(DCUx);
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* De-initialize dcu register value */
DCUx->CTL = 0u;
DCUx->INTSEL = 0u;
DCUx->FLAGCLR = 0x7Fu;
*TRGSELx = EVT_MAX;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set DCU operation mode.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enMode DCU operation mode
** \arg DcuInvalid Invalid
** \arg DcuOpAdd Operation: Add
** \arg DcuOpSub Operation: Sub
** \arg DcuHwTrigOpAdd Operation: Hardware trigger Add
** \arg DcuHwTrigOpSub Operation: Hardware trigger Sub
** \arg DcuOpCompare Operation: Compare
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_SetOperationMode(M4_DCU_TypeDef *DCUx,
en_dcu_operation_mode_t enMode)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU_OPERATION(enMode));
DCUx->CTL_f.MODE = (uint32_t)enMode;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get DCU operation mode.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
**
** \retval DcuInvalid Invalid
** \retval DcuOpAdd Operation: Add
** \retval DcuOpSub Operation: Sub
** \retval DcuHwTrigOpAdd Operation: Hardware trigger Add
** \retval DcuHwTrigOpSub Operation: Hardware trigger Sub
** \retval DcuOpCompare Operation: Compare
**
******************************************************************************/
en_dcu_operation_mode_t DCU_GetOperationMode(M4_DCU_TypeDef *DCUx)
{
/* Check for DCUx pointer */
DDL_ASSERT(IS_VALID_DCU(DCUx));
return (en_dcu_operation_mode_t)DCUx->CTL_f.MODE;
}
/**
*******************************************************************************
** \brief Set DCU data size.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enSize DCU data size
** \arg DcuDataBit8 8 bit
** \arg DcuDataBit16 16 bit
** \arg DcuDataBit32 32 bit
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_SetDataSize(M4_DCU_TypeDef *DCUx, en_dcu_data_size_t enSize)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU_DATAZ_SIZE(enSize));
DCUx->CTL_f.DATASIZE = (uint32_t)enSize;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get DCU data size.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
**
** \retval DcuDataBit8 8 bit
** \retval DcuDataBit16 16 bit
** \retval DcuDataBit32 32 bit
**
******************************************************************************/
en_dcu_data_size_t DCU_GetDataSize(M4_DCU_TypeDef *DCUx)
{
/* Check for DCUx pointer */
DDL_ASSERT(IS_VALID_DCU(DCUx));
return (en_dcu_data_size_t)(DCUx->CTL_f.DATASIZE);
}
/**
*******************************************************************************
** \brief Set DCU interrup window.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enIntWinMode Interrupt window mode
** \arg DcuIntInvalid DCU don't occur interrupt
** \arg DcuWinIntInvalid DCU window interrupt is invalid.
** \arg DcuInsideWinCmpInt DCU occur interrupt when DATA2 <= DATA0 <= DATA2
** \arg DcuOutsideWinCmpInt DCU occur interrupt when DATA0 > DATA1 or DATA0 < DATA2
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_SetIntWinMode(M4_DCU_TypeDef *DCUx,
en_dcu_int_win_mode_t enIntWinMode)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU_INT_WIN_MODE(enIntWinMode));
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
DCUx->INTSEL_f.INT_WIN = (uint32_t)enIntWinMode;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get DCU interrup window.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
**
** \retval DcuIntInvalid DCU don't occur interrupt
** \retval DcuWinIntInvalid DCU window interrupt is invalid.
** \retval DcuInsideWinCmpInt DCU occur interrupt when DATA2 <= DATA0 <= DATA2
** \retval DcuOutsideWinCmpInt DCU occur interrupt when DATA0 > DATA1 or DATA0 < DATA2
**
******************************************************************************/
en_dcu_int_win_mode_t DCU_GetIntWinMode(M4_DCU_TypeDef *DCUx)
{
/* Check for DCUx pointer */
DDL_ASSERT(IS_VALID_DCU(DCUx));
return (en_dcu_int_win_mode_t)(DCUx->INTSEL_f.INT_WIN);
}
/**
*******************************************************************************
** \brief Set DCU compare trigger mode.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enTriggerMode DCU compare trigger mode
** \arg DcuCmpTrigbyData0 DCU compare triggered by DATA0
** \arg DcuCmpTrigbyData012 DCU compare triggered by DATA0 or DATA1 or DATA2
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_SetCmpTriggerMode(M4_DCU_TypeDef *DCUx,
en_dcu_cmp_trigger_mode_t enTriggerMode)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU_CMP_TRIG_MODE(enTriggerMode));
DCUx->CTL_f.COMP_TRG = (uint32_t)enTriggerMode;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get DCU compare trigger mode.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
**
** \retval DcuCmpTrigbyData0 DCU compare triggered by DATA0
** \retval DcuCmpTrigbyData012 DCU compare triggered by DATA0 or DATA1 or DATA2
**
******************************************************************************/
en_dcu_cmp_trigger_mode_t DCU_GetCmpTriggerMode(M4_DCU_TypeDef *DCUx)
{
/* Check for DCUx pointer */
DDL_ASSERT(IS_VALID_DCU(DCUx));
return (en_dcu_cmp_trigger_mode_t)(DCUx->CTL_f.COMP_TRG);
}
/**
*******************************************************************************
** \brief Enable DCU interrupt.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enCmd DCU interrupt state
** \arg Enable Enable the DCU interrupt function
** \arg Disable Disable the DCU interrupt function
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_IrqCmd(M4_DCU_TypeDef *DCUx, en_functional_state_t enCmd)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* Check the parameters */
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
DCUx->CTL_f.INTEN = (uint32_t)(enCmd);
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get the specified DCU flag
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enFlag The specified DCU flag
** \arg DcuIntOp DCU overflow or underflow
** \arg DcuIntLs2 DCU DATA0 < DATA2
** \arg DcuIntEq2 DCU DATA0 = DATA2
** \arg DcuIntGt2 DCU DATA0 > DATA2
** \arg DcuIntLs1 DCU DATA0 < DATA1
** \arg DcuIntEq1 DCU DATA0 = DATA1
** \arg DcuIntGt1 DCU DATA0 > DATA1
**
** \retval Set Flag is set.
** \retval Reset Flag is reset or enStatus is invalid.
**
******************************************************************************/
en_flag_status_t DCU_GetIrqFlag(M4_DCU_TypeDef *DCUx, en_dcu_flag_t enFlag)
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU(DCUx));
DDL_ASSERT(IS_VALID_DCU_INT(enFlag));
return ((DCUx->FLAG & enFlag) ? Set : Reset);
}
/**
*******************************************************************************
** \brief Clear the specified DCU flag
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enFlag the specified DCU flag
** \arg DcuIntOp DCU overflow or underflow
** \arg DcuIntLs2 DCU DATA0 < DATA2
** \arg DcuIntEq2 DCU DATA0 = DATA2
** \arg DcuIntGt2 DCU DATA0 > DATA2
** \arg DcuIntLs1 DCU DATA0 < DATA1
** \arg DcuIntEq1 DCU DATA0 = DATA1
** \arg DcuIntGt1 DCU DATA0 > DATA1
**
** \retval Ok Clear flag successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_ClearIrqFlag(M4_DCU_TypeDef *DCUx, en_dcu_flag_t enFlag)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU_INT(enFlag));
DCUx->FLAGCLR = (uint32_t)enFlag;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Enable/Disable DCU interrupt.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enIntSel DCU interrupt selection
** \arg DcuIntOp DCU overflow or underflow
** \arg DcuIntLs2 DCU DATA0 < DATA2
** \arg DcuIntEq2 DCU DATA0 = DATA2
** \arg DcuIntGt2 DCU DATA0 > DATA2
** \arg DcuIntLs1 DCU DATA0 < DATA1
** \arg DcuIntEq1 DCU DATA0 = DATA1
** \arg DcuIntGt1 DCU DATA0 > DATA1
** \param [in] enCmd DCU interrupt functional state
** \arg Enable Enable the specified DCU interrupt function
** \arg Disable Disable the specified DCU interrupt function
**
** \retval Ok Configure successfully.
** \retval ErrorInvalidParameter If one of following cases matches:
** - DCUx is invalid
** - enIntSel is invalid
**
******************************************************************************/
en_result_t DCU_IrqSelCmd(M4_DCU_TypeDef *DCUx,
en_dcu_int_sel_t enIntSel,
en_functional_state_t enCmd)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU_INT(enIntSel));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
enRet = Ok;
switch(enIntSel)
{
case DcuIntOp:
DCUx->INTSEL_f.INT_OP = (uint32_t)enCmd;
break;
case DcuIntLs2:
DCUx->INTSEL_f.INT_LS2 = (uint32_t)enCmd;
break;
case DcuIntEq2:
DCUx->INTSEL_f.INT_EQ2 = (uint32_t)enCmd;
break;
case DcuIntGt2:
DCUx->INTSEL_f.INT_GT2 = (uint32_t)enCmd;
break;
case DcuIntLs1:
DCUx->INTSEL_f.INT_LS1 = (uint32_t)enCmd;
break;
case DcuIntEq1:
DCUx->INTSEL_f.INT_EQ1 = (uint32_t)enCmd;
break;
case DcuIntGt1:
DCUx->INTSEL_f.INT_GT1 = (uint32_t)enCmd;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Read DCU register DATAx
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enDataReg The specified DATA register.
** \arg DcuRegisterData0 DCU register DATA0
** \arg DcuRegisterData1 DCU register DATA1
** \arg DcuRegisterData2 DCU register DATA2
**
** \retval DCU register DATAx value
**
******************************************************************************/
uint8_t DCU_ReadDataByte(M4_DCU_TypeDef *DCUx,
en_dcu_data_register_t enDataReg)
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU(DCUx));
DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
return *(uint8_t *)DCU_DATAx(DCUx, enDataReg);
}
/**
*******************************************************************************
** \brief Write DCU register DATAx
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enDataReg The specified DATA register.
** \arg DcuRegisterData0 DCU register DATA0
** \arg DcuRegisterData1 DCU register DATA1
** \arg DcuRegisterData2 DCU register DATA2
** \param [in] u8Data The data will be written.
**
** \retval Ok Write successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_WriteDataByte(M4_DCU_TypeDef *DCUx,
en_dcu_data_register_t enDataReg,
uint8_t u8Data)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
*(uint8_t *)DCU_DATAx(DCUx, enDataReg) = u8Data;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Read DCU register DATAx
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enDataReg The specified DATA register.
** \arg DcuRegisterData0 DCU register DATA0
** \arg DcuRegisterData1 DCU register DATA1
** \arg DcuRegisterData2 DCU register DATA2
**
** \retval DCU register DATAx value
**
******************************************************************************/
uint16_t DCU_ReadDataHalfWord(M4_DCU_TypeDef *DCUx,
en_dcu_data_register_t enDataReg)
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU(DCUx));
DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
return *(uint16_t *)DCU_DATAx(DCUx, enDataReg);
}
/**
*******************************************************************************
** \brief Write DCU register DATAx
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enDataReg The specified DATA register.
** \arg DcuRegisterData0 DCU register DATA0
** \arg DcuRegisterData1 DCU register DATA1
** \arg DcuRegisterData2 DCU register DATA2
** \param [in] u16Data The data will be written.
**
** \retval Ok Write successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_WriteDataHalfWord(M4_DCU_TypeDef *DCUx,
en_dcu_data_register_t enDataReg,
uint16_t u16Data)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
*(uint16_t *)DCU_DATAx(DCUx, enDataReg) = u16Data;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Read DCU register DATAx
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enDataReg The specified DATA register.
** \arg DcuRegisterData0 DCU register DATA0
** \arg DcuRegisterData1 DCU register DATA1
** \arg DcuRegisterData2 DCU register DATA2
**
** \retval DCU register DATAx value
**
******************************************************************************/
uint32_t DCU_ReadDataWord(M4_DCU_TypeDef *DCUx,
en_dcu_data_register_t enDataReg)
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU(DCUx));
DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
return *(uint32_t *)DCU_DATAx(DCUx, enDataReg);
}
/**
*******************************************************************************
** \brief Write DCU register DATAx
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enDataReg The specified DATA register.
** \arg DcuRegisterData0 DCU register DATA0
** \arg DcuRegisterData1 DCU register DATA1
** \arg DcuRegisterData2 DCU register DATA2
** \param [in] u32Data The data will be written.
**
** \retval Ok Write successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_WriteDataWord(M4_DCU_TypeDef *DCUx,
en_dcu_data_register_t enDataReg,
uint32_t u32Data)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check for DCUx pointer */
if (IS_VALID_DCU(DCUx))
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_DCU_DATA_REG(enDataReg));
*(uint32_t *)DCU_DATAx(DCUx, enDataReg) = u32Data;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set DCU trigger source number
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enTriggerSrc The trigger source.
** \arg This parameter can be any value of @ref en_event_src_t
**
** \retval Ok Write successfully.
** \retval ErrorInvalidParameter DCUx is invalid
**
******************************************************************************/
en_result_t DCU_SetTriggerSrc(M4_DCU_TypeDef *DCUx,
en_event_src_t enTriggerSrc)
{
en_result_t enRet = ErrorInvalidParameter;
__IO uint32_t *TRGSELx = DCU_TRGSELx(DCUx);
if (NULL != TRGSELx)
{
/* Check the parameters */
DDL_ASSERT(IS_VALID_TRG_SRC_EVENT(enTriggerSrc));
*TRGSELx = (*TRGSELx & (~((uint32_t)EVT_MAX))) | (uint32_t)enTriggerSrc;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable DCU common trigger.
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
** \param [in] enComTrigger DCU common trigger selection. See @ref en_dcu_com_trigger_t for details.
** \param [in] enState Enable or disable the specified common trigger.
**
** \retval None.
**
******************************************************************************/
void DCU_ComTriggerCmd(M4_DCU_TypeDef *DCUx,
en_dcu_com_trigger_t enComTrigger,
en_functional_state_t enState)
{
uint32_t u32ComTrig = (uint32_t)enComTrigger;
__IO uint32_t *TRGSELx = DCU_TRGSELx(DCUx);
if (NULL != TRGSELx)
{
DDL_ASSERT(IS_DCU_COM_TRIGGER(enComTrigger));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
if (enState == Enable)
{
*TRGSELx |= (u32ComTrig << 30u);
}
else
{
*TRGSELx &= ~(u32ComTrig << 30u);
}
}
}
/**
*******************************************************************************
** \brief Get DCU trigger source register address
**
** \param [in] DCUx Pointer to DCU instance register base
** \arg M4_DCU1 DCU unit 1 instance register base
** \arg M4_DCU2 DCU unit 2 instance register base
** \arg M4_DCU3 DCU unit 3 instance register base
** \arg M4_DCU4 DCU unit 4 instance register base
**
** \retval DCUx_TRGSEL address DCUx is valid
** \retval NULL DCUx is invalid
**
******************************************************************************/
static __IO uint32_t* DCU_TRGSELx(const M4_DCU_TypeDef *DCUx)
{
__IO uint32_t *TRGSELx = NULL;
if (M4_DCU1 == DCUx)
{
TRGSELx = &M4_AOS->DCU1_TRGSEL;
}
else if (M4_DCU2 == DCUx)
{
TRGSELx = &M4_AOS->DCU2_TRGSEL;
}
else if (M4_DCU3 == DCUx)
{
TRGSELx = &M4_AOS->DCU3_TRGSEL;
}
else if (M4_DCU4 == DCUx)
{
TRGSELx = &M4_AOS->DCU4_TRGSEL;
}
else
{
TRGSELx = NULL;
}
return TRGSELx;
}
//@} // DcuGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,938 @@
/******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_efm.c
**
** A detailed description is available at
** @link EfmGroup EFM description @endlink
**
** - 2018-10-29 CDT First version for Device Driver Library of EFM.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_efm.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup EfmGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define EFM_LOCK (0x00000000u)
#define EFM_UNLOCK (0x00000001u)
#define EFM_KEY1 (0x0123ul)
#define EFM_KEY2 (0x3210ul)
#define EFM_PROTECT_ADDR_MSK (0x000FFFFFu)
/* Parameter validity check for pointer. */
#define IS_VALID_POINTER(x) (NULL != (x))
/* Parameter validity check for flash latency. */
#define IS_VALID_FLASH_LATENCY(x) \
( ((x) == EFM_LATENCY_0) || \
((x) == EFM_LATENCY_1) || \
((x) == EFM_LATENCY_2) || \
((x) == EFM_LATENCY_3) || \
((x) == EFM_LATENCY_4) || \
((x) == EFM_LATENCY_5) || \
((x) == EFM_LATENCY_6) || \
((x) == EFM_LATENCY_7) || \
((x) == EFM_LATENCY_8) || \
((x) == EFM_LATENCY_9) || \
((x) == EFM_LATENCY_10) || \
((x) == EFM_LATENCY_11) || \
((x) == EFM_LATENCY_12) || \
((x) == EFM_LATENCY_13) || \
((x) == EFM_LATENCY_14) || \
((x) == EFM_LATENCY_15))
/* Parameter validity check for read mode. */
#define IS_VALID_READ_MD(MD) \
( ((MD) == NormalRead) || \
((MD) == UltraPowerRead))
/* Parameter validity check for erase/program mode. */
#define IS_VALID_ERASE_PGM_MD(MD) \
( ((MD) == EFM_MODE_READONLY) || \
((MD) == EFM_MODE_SINGLEPROGRAM) || \
((MD) == EFM_MODE_SINGLEPROGRAMRB) || \
((MD) == EFM_MODE_SEQUENCEPROGRAM) || \
((MD) == EFM_MODE_SECTORERASE) || \
((MD) == EFM_MODE_CHIPERASE))
/* Parameter validity check for flash flag. */
#define IS_VALID_FLASH_FLAG(flag) \
( ((flag) == EFM_FLAG_WRPERR) || \
((flag) == EFM_FLAG_PEPRTERR) || \
((flag) == EFM_FLAG_PGSZERR) || \
((flag) == EFM_FLAG_PGMISMTCH) || \
((flag) == EFM_FLAG_EOP) || \
((flag) == EFM_FLAG_COLERR) || \
((flag) == EFM_FLAG_RDY))
/* Parameter validity check for flash clear flag. */
#define IS_VALID_CLEAR_FLASH_FLAG(flag) \
( ((flag) == EFM_FLAG_WRPERR) || \
((flag) == EFM_FLAG_PEPRTERR) || \
((flag) == EFM_FLAG_PGSZERR) || \
((flag) == EFM_FLAG_PGMISMTCH) || \
((flag) == EFM_FLAG_EOP) || \
((flag) == EFM_FLAG_COLERR))
/* Parameter validity check for flash interrupt. */
#define IS_VALID_EFM_INT_SEL(int) \
( ((int) == PgmErsErrInt) || \
((int) == EndPgmInt) || \
((int) == ColErrInt))
/* Parameter validity check for flash address. */
#define IS_VALID_FLASH_ADDR(addr) \
( ((addr) == 0x00000000u) || \
(((addr) >= 0x00000001u) && \
((addr) <= 0x0007FFDFu)))
/* Parameter validity check for flash address. */
#define IS_VALID_OTP_LOCK_ADDR(addr) \
( ((addr) >= 0x03000FC0u) || \
((addr) <= 0x03000FF8u))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Unlock the flash.
**
** \param None
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_Unlock(void)
{
M4_EFM->FAPRT = EFM_KEY1;
M4_EFM->FAPRT = EFM_KEY2;
}
/**
*******************************************************************************
** \brief Lock the flash.
**
** \param None
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_Lock(void)
{
if(EFM_UNLOCK == M4_EFM->FAPRT)
{
M4_EFM->FAPRT = EFM_KEY2;
M4_EFM->FAPRT = EFM_KEY2;
}
}
/**
*******************************************************************************
** \brief Enable or disable the flash.
**
** \param [in] enNewState The new state of the flash.
** \arg Enable Enable flash.
** \arg Disable Stop flash.
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_FlashCmd(en_functional_state_t enNewState)
{
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
M4_EFM->FSTP_f.FSTP = ((Enable == enNewState) ? 0ul : 1ul);
}
/**
*******************************************************************************
** \brief Sets the code latency value..
**
** \param [in] u32Latency specifies the FLASH Latency value.
** \arg EFM_LATENCY_0 FLASH 0 Latency cycle
** \arg EFM_LATENCY_1 FLASH 1 Latency cycle
** \arg EFM_LATENCY_2 FLASH 2 Latency cycles
** \arg EFM_LATENCY_3 FLASH 3 Latency cycles
** \arg EFM_LATENCY_4 FLASH 4 Latency cycles
** \arg EFM_LATENCY_5 FLASH 5 Latency cycles
** \arg EFM_LATENCY_6 FLASH 6 Latency cycles
** \arg EFM_LATENCY_7 FLASH 7 Latency cycles
** \arg EFM_LATENCY_8 FLASH 8 Latency cycles
** \arg EFM_LATENCY_9 FLASH 9 Latency cycles
** \arg EFM_LATENCY_10 FLASH 10 Latency cycles
** \arg EFM_LATENCY_11 FLASH 11 Latency cycles
** \arg EFM_LATENCY_12 FLASH 12 Latency cycles
** \arg EFM_LATENCY_13 FLASH 13 Latency cycles
** \arg EFM_LATENCY_14 FLASH 14 Latency cycles
** \arg EFM_LATENCY_15 FLASH 15 Latency cycles
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_SetLatency(uint32_t u32Latency)
{
DDL_ASSERT(IS_VALID_FLASH_LATENCY(u32Latency));
M4_EFM->FRMC_f.FLWT = u32Latency;
}
/**
*******************************************************************************
** \brief Enable or disable the flash instruction cache.
**
** \param [in] enNewState The new state of the flash instruction cache.
** \arg Enable Enable flash instruction cache.
** \arg Disable Disable flash instruction cache.
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_InstructionCacheCmd(en_functional_state_t enNewState)
{
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
M4_EFM->FRMC_f.CACHE = enNewState;
}
/**
*******************************************************************************
** \brief Enable or disable the data cache reset.
**
** \param [in] enNewState The new state of the data cache reset.
** \arg Enable Enable data cache reset.
** \arg Disable Disable data cache reset.
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_DataCacheRstCmd(en_functional_state_t enNewState)
{
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
M4_EFM->FRMC_f.CRST = enNewState;
}
/**
*******************************************************************************
** \brief Set the flash read mode.
**
** \param [in] enReadMD The flash read mode.
** \arg NormalRead Normal read mode.
** \arg UltraPowerRead Ultra_Low power read mode.
**
** \retval None.
**
** \note None
**
******************************************************************************/
void EFM_SetReadMode(en_efm_read_md_t enReadMD)
{
DDL_ASSERT(IS_VALID_READ_MD(enReadMD));
M4_EFM->FRMC_f.SLPMD = enReadMD;
}
/**
*******************************************************************************
** \brief Enable or disable erase / program.
**
** \param [in] enNewState The new state of the erase / program.
** \arg Enable Enable erase / program.
** \arg Disable Disable erase / program.
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_ErasePgmCmd(en_functional_state_t enNewState)
{
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
M4_EFM->FWMC_f.PEMODE = enNewState;
}
/**
*******************************************************************************
** \brief Set the flash erase program mode.
**
** \param [in] u32Mode The flash erase program mode.
** \arg EFM_MODE_READONLY The flash read only.
** \arg EFM_MODE_SINGLEPROGRAM The flash single program.
** \arg EFM_MODE_SINGLEPROGRAMRB The flash single program with read back.
** \arg EFM_MODE_SEQUENCEPROGRAM The flash sequence program.
** \arg EFM_MODE_SECTORERASE The flash sector erase.
** \arg EFM_MODE_CHIPERASE The flash mass erase.
**
** \retval en_result_t.
**
** \note None
**
******************************************************************************/
en_result_t EFM_SetErasePgmMode(uint32_t u32Mode)
{
en_result_t enRet = Ok;
uint16_t u16Timeout = 0u;
DDL_ASSERT(IS_VALID_ERASE_PGM_MD(u32Mode));
while(1ul != M4_EFM->FSR_f.RDY)
{
u16Timeout++;
if(u16Timeout > 0x1000u)
{
enRet = ErrorTimeout;
break;
}
}
if(Ok == enRet)
{
M4_EFM->FWMC_f.PEMODE = Enable;
M4_EFM->FWMC_f.PEMOD = u32Mode;
M4_EFM->FWMC_f.PEMODE = Disable;
}
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable the specified interrupt.
**
** \param [in] enInt The specified interrupt.
** \arg PgmErsErrInt Program erase error interrupt.
** \arg EndPgmInt End of Program interrupt.
** \arg ReadErrInt Read collided error flag.
**
** \param [in] enNewState The new state of the specified interrupt.
** \arg Enable Enable the specified interrupt.
** \arg Disable Disable the specified interrupt.
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_InterruptCmd(en_efm_int_sel_t enInt, en_functional_state_t enNewState)
{
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
DDL_ASSERT(IS_VALID_EFM_INT_SEL(enInt));
switch(enInt)
{
case PgmErsErrInt:
M4_EFM->FITE_f.PEERRITE = enNewState;
break;
case EndPgmInt:
M4_EFM->FITE_f.OPTENDITE = enNewState;
break;
case ColErrInt:
M4_EFM->FITE_f.COLERRITE = enNewState;
break;
default:
break;
}
}
/**
*******************************************************************************
** \brief Checks whether the specified FLASH flag is set or not..
**
** \param [in] u32flag Specifies the FLASH flag to check.
** \arg EFM_FLAG_WRPERR Flash write protect error flag.
** \arg EFM_FLAG_PEPRTERR Flash program protect area error flag.
** \arg EFM_FLAG_PGSZERR Flash program size error flag.
** \arg EFM_FLAG_PGMISMTCH Flash program miss match flag.
** \arg EFM_FLAG_EOP Flash end of program flag.
** \arg EFM_FLAG_COLERR Flash collision error flag.
** \arg EFM_FLAG_RDY Flash ready flag.
**
** \retval The flash status.
**
** \note None
**
******************************************************************************/
en_flag_status_t EFM_GetFlagStatus(uint32_t u32flag)
{
DDL_ASSERT(IS_VALID_FLASH_FLAG(u32flag));
return ((0ul == (M4_EFM->FSR & u32flag)) ? Reset :Set);
}
/**
*******************************************************************************
** \brief Checks whether the specified FLASH flag is set or not..
**
** \param [in] u32flag Specifies the FLASH flag to clear.
** \arg EFM_FLAG_WRPERR Flash write protect error flag.
** \arg EFM_FLAG_PEPRTERR Flash program protect area error flag.
** \arg EFM_FLAG_PGSZERR Flash program size error flag.
** \arg EFM_FLAG_PGMISMTCH Flash program miss match flag.
** \arg EFM_FLAG_EOP Flash end of program flag.
** \arg EFM_FLAG_COLERR Flash collision error flag.
**
** \retval The flash status.
**
** \note None
**
******************************************************************************/
void EFM_ClearFlag(uint32_t u32flag)
{
//DDL_ASSERT(IS_VALID_CLEAR_FLASH_FLAG(u32flag));
M4_EFM->FSCLR = u32flag;
}
/**
*******************************************************************************
** \brief Get the flash status.
**
** \param None
**
** \retval The flash status.
**
** \note None
**
******************************************************************************/
en_efm_flash_status_t EFM_GetStatus(void)
{
en_efm_flash_status_t enFlashStatus = FlashEOP;
if(1ul == M4_EFM->FSR_f.RDY )
{
enFlashStatus = FlashReady;
}
else if(1ul == M4_EFM->FSR_f.COLERR)
{
enFlashStatus = FlashRWErr;
}
else if(1ul == M4_EFM->FSR_f.OPTEND)
{
enFlashStatus = FlashEOP;
}
else if(1ul == M4_EFM->FSR_f.PGMISMTCH)
{
enFlashStatus = FlashPgMissMatch;
}
else if(1ul == M4_EFM->FSR_f.PGSZERR)
{
enFlashStatus = FlashPgSizeErr;
}
else if(1ul == M4_EFM->FSR_f.PEPRTERR)
{
enFlashStatus = FlashPgareaPErr;
}
else if(1ul == M4_EFM->FSR_f.PEWERR)
{
enFlashStatus = FlashWRPErr;
}
else
{
//else
}
return enFlashStatus;
}
/**
*******************************************************************************
** \brief Set flash the windows protect address.
**
** \param [in] stcAddr The specified windows protect address.
** \arg StartAddr The start of windows protect address.
** \arg EndAddr The end of windows protect address.
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_SetWinProtectAddr(stc_efm_win_protect_addr_t stcAddr)
{
M4_EFM->FPMTSW_f.FPMTSW = (stcAddr.StartAddr & EFM_PROTECT_ADDR_MSK);
M4_EFM->FPMTEW_f.FPMTEW = (stcAddr.EndAddr & EFM_PROTECT_ADDR_MSK);
}
/**
*******************************************************************************
** \brief Set bus state while flash program & erase.
**
** \param [in] enState The specified bus state while flash program & erase.
** \arg BusBusy The bus busy.
** \arg BusRelease The bus release.
**
** \retval None
**
** \note None
**
******************************************************************************/
void EFM_SetBusState(en_efm_bus_sta_t enState)
{
M4_EFM->FWMC_f.BUSHLDCTL = enState;
}
/**
*******************************************************************************
** \brief Flash single program without read back.
**
** \param [in] u32Addr The specified program address.
** \param [in] u32Data The specified program data.
**
** \retval en_result_t
**
** \note None
**
******************************************************************************/
en_result_t EFM_SingleProgram(uint32_t u32Addr, uint32_t u32Data)
{
en_result_t enRet = Ok;
uint8_t u8tmp;
uint16_t u16Timeout = 0u;
DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
/* CLear the error flag. */
EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
/* read back CACHE */
u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
M4_EFM->FRMC_f.CACHE = Disable;
/* Enable program. */
EFM_ErasePgmCmd(Enable);
/* Set single program mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_SINGLEPROGRAM;
/* program data. */
*(uint32_t*)u32Addr = u32Data;
while(1ul != M4_EFM->FSR_f.RDY)
{
u16Timeout++;
if(u16Timeout > 0x1000u)
{
enRet = ErrorTimeout;
}
}
if(u32Data != *(uint32_t*)u32Addr)
{
enRet = Error;
}
EFM_ClearFlag(EFM_FLAG_EOP);
/* Set read only mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
EFM_ErasePgmCmd(Disable);
/* recover CACHE */
M4_EFM->FRMC_f.CACHE = u8tmp;
return enRet;
}
/**
*******************************************************************************
** \brief Flash single program with read back.
**
** \param [in] u32Addr The specified program address.
** \param [in] u32Data The specified program data.
**
** \retval en_result_t
**
** \note None
**
******************************************************************************/
en_result_t EFM_SingleProgramRB(uint32_t u32Addr, uint32_t u32Data)
{
en_result_t enRet = Ok;
uint8_t u8tmp = 0u;
uint16_t u16Timeout = 0u;
DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
/* CLear the error flag. */
EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
/* read back CACHE */
u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
M4_EFM->FRMC_f.CACHE = Disable;
/* Enable program. */
EFM_ErasePgmCmd(Enable);
/* Set single program with read back mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_SINGLEPROGRAMRB;
/* program data. */
*(uint32_t*)u32Addr = u32Data;
while(1ul != M4_EFM->FSR_f.RDY)
{
u16Timeout++;
if(u16Timeout > 0x1000u)
{
enRet = ErrorTimeout;
}
}
if(1ul == M4_EFM->FSR_f.PGMISMTCH)
{
enRet = Error;
}
EFM_ClearFlag(EFM_FLAG_EOP);
/* Set read only mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
EFM_ErasePgmCmd(Disable);
/* recover CACHE */
M4_EFM->FRMC_f.CACHE = u8tmp;
return enRet;
}
static void *EFM_Memcpy(void *pvDst, void *pvSrc, uint32_t u32Count)
{
uint8_t *u8TmpDst = (uint8_t *)pvDst;
uint8_t *u8TmpSrc = (uint8_t *)pvSrc;
DDL_ASSERT(IS_VALID_POINTER(pvDst));
DDL_ASSERT(IS_VALID_POINTER(pvSrc));
while (u32Count--)
{
*u8TmpDst++ = *u8TmpSrc++;
}
return pvDst;
}
/**
*******************************************************************************
** \brief Flash sequence program.
**
** \param [in] u32Addr The specified program address.
** \param [in] u32Len The len of specified program data.
** \param [in] *pBuf The pointer of specified program data.
**
** \retval en_result_t
**
** \note None
**
******************************************************************************/
en_result_t EFM_SequenceProgram(uint32_t u32Addr, uint32_t u32Len, void *pBuf)
{
en_result_t enRet = Ok;
uint8_t u8tmp;
uint32_t i;
uint16_t u16Timeout = 0u;
uint32_t u32Tmp = 0xFFFFFFFFul;
uint32_t *u32pSrc = pBuf;
uint32_t *u32pDest = (uint32_t *)u32Addr;
uint32_t u32LoopWords = u32Len >> 2ul;
uint32_t u32RemainBytes = u32Len % 4ul;
DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
DDL_ASSERT(IS_VALID_POINTER(pBuf));
/* CLear the error flag. */
EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
/* read back CACHE */
u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
M4_EFM->FRMC_f.CACHE = Disable;
/* Enable program. */
EFM_ErasePgmCmd(Enable);
/* Set sequence program mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_SEQUENCEPROGRAM;
/* clear read collided error flag.*/
EFM_ClearFlag(EFM_FLAG_COLERR);
EFM_ClearFlag(EFM_FLAG_WRPERR);
/* program data. */
for(i = 0ul; i < u32LoopWords; i++)
{
*u32pDest++ = *u32pSrc++;
/* wait operate end. */
while(1ul != M4_EFM->FSR_f.OPTEND)
{
u16Timeout++;
if(u16Timeout > 0x1000u)
{
enRet = ErrorTimeout;
}
}
/* clear end flag. */
EFM_ClearFlag(EFM_FLAG_EOP);
}
if(u32RemainBytes)
{
EFM_Memcpy(&u32Tmp, u32pSrc, u32RemainBytes);
*u32pDest++ = u32Tmp;
}
/* Set read only mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
u16Timeout = 0u;
while(1ul != M4_EFM->FSR_f.RDY)
{
u16Timeout++;
if(u16Timeout > 0x1000u)
{
enRet = ErrorTimeout;
}
}
EFM_ClearFlag(EFM_FLAG_EOP);
EFM_ErasePgmCmd(Disable);
/* recover CACHE */
M4_EFM->FRMC_f.CACHE = u8tmp;
return enRet;
}
/**
*******************************************************************************
** \brief Flash sector erase.
**
** \param [in] u32Addr The uncertain(random) address in the specified sector.
**
** \retval en_result_t
**
** \note The address should be word align.
**
******************************************************************************/
en_result_t EFM_SectorErase(uint32_t u32Addr)
{
uint8_t u8tmp;
uint16_t u16Timeout = 0u;
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
/* CLear the error flag. */
EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
/* read back CACHE */
u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
M4_EFM->FRMC_f.CACHE = Disable;
/* Enable erase. */
EFM_ErasePgmCmd(Enable);
/* Set sector erase mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_SECTORERASE;
*(uint32_t*)u32Addr = 0x12345678u;
while(1ul != M4_EFM->FSR_f.RDY)
{
u16Timeout++;
if(u16Timeout > 0x1000u)
{
enRet = ErrorTimeout;
}
}
EFM_ClearFlag(EFM_FLAG_EOP);
/* Set read only mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
EFM_ErasePgmCmd(Disable);
/* recover CACHE */
M4_EFM->FRMC_f.CACHE = u8tmp;
return enRet;
}
/**
*******************************************************************************
** \brief Flash mass erase.
**
** \param [in] u32Addr The uncertain(random) address in the flash.
**
** \retval en_result_t
**
** \note The address should be word align.
**
******************************************************************************/
en_result_t EFM_MassErase(uint32_t u32Addr)
{
uint8_t u8tmp;
uint16_t u16Timeout = 0u;
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_FLASH_ADDR(u32Addr));
/* CLear the error flag. */
EFM_ClearFlag(EFM_FLAG_WRPERR | EFM_FLAG_PEPRTERR | EFM_FLAG_PGSZERR |
EFM_FLAG_PGMISMTCH | EFM_FLAG_EOP | EFM_FLAG_COLERR);
/* read back CACHE */
u8tmp = (uint8_t)M4_EFM->FRMC_f.CACHE;
M4_EFM->FRMC_f.CACHE = Disable;
/* Enable erase. */
EFM_ErasePgmCmd(Enable);
/* Set sector erase mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_CHIPERASE;
*(uint32_t*)u32Addr = 0x12345678u;
while(1ul != M4_EFM->FSR_f.RDY)
{
u16Timeout++;
if(u16Timeout > 0x1000u)
{
enRet = ErrorTimeout;
}
}
EFM_ClearFlag(EFM_FLAG_EOP);
/* Set read only mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
EFM_ErasePgmCmd(Disable);
/* recover CACHE */
M4_EFM->FRMC_f.CACHE = u8tmp;
return enRet;
}
/**
*******************************************************************************
** \brief Get flash switch status.
**
** \param None.
**
** \retval en_flag_status_t
** \arg Set The flash has switched, the start address is sector1.
** \arg Reset The flash did not switch, the start address is sector0.
**
** \note None
**
******************************************************************************/
en_flag_status_t EFM_GetSwitchStatus(void)
{
return ((0u == M4_EFM->FSWP_f.FSWP) ? Set : Reset);
}
/**
*******************************************************************************
** \brief Lock OTP data block.
**
** \param u32Addr The addr to lock.
**
** \retval en_result_t
**
** \note None
**
******************************************************************************/
en_result_t EFM_OtpLock(uint32_t u32Addr)
{
DDL_ASSERT(IS_VALID_OTP_LOCK_ADDR(u32Addr));
uint16_t u16Timeout = 0u;
en_result_t enRet = Ok;
/* Enable program. */
EFM_ErasePgmCmd(Enable);
/* Set single program mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_SINGLEPROGRAM;
/* Lock the otp block. */
*(uint32_t*)u32Addr = 0ul;
while(1ul != M4_EFM->FSR_f.RDY)
{
u16Timeout++;
if(u16Timeout > 0x1000u)
{
enRet = ErrorTimeout;
}
}
EFM_ClearFlag(EFM_FLAG_EOP);
/* Set read only mode. */
M4_EFM->FWMC_f.PEMOD = EFM_MODE_READONLY;
EFM_ErasePgmCmd(Disable);
return enRet;
}
/**
*******************************************************************************
** \brief read unique ID.
**
** \param None
**
** \retval uint32_t
**
** \note None
**
******************************************************************************/
stc_efm_unique_id_t EFM_ReadUID(void)
{
stc_efm_unique_id_t stcUID;
stcUID.uniqueID1 = M4_EFM->UQID1;
stcUID.uniqueID2 = M4_EFM->UQID2;
stcUID.uniqueID3 = M4_EFM->UQID3;
return stcUID;
}
//@} // EfmGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,483 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_emb.c
**
** A detailed description is available at
** @link EMBGroup EMB description @endlink
**
** - 2018-11-24 CDT First version for Device Driver Library of EMB.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_emb.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup EMBGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter valid check for emb unit */
#define IS_VALID_EMB_UNIT(__EMBx__) \
( (M4_EMB1 == (__EMBx__)) || \
(M4_EMB2 == (__EMBx__)) || \
(M4_EMB3 == (__EMBx__)) || \
(M4_EMB4 == (__EMBx__)))
/*!< Parameter valid check for emb status*/
#define IS_VALID_EMB_STATUS_TYPE(x) \
( (EMBFlagPortIn == (x)) || \
(EMBFlagPWMSame == (x)) || \
(EMBFlagCmp == (x)) || \
(EMBFlagOSCFail == (x)) || \
(EMBPortInState == (x)) || \
(EMBPWMState == (x)))
/*!< Parameter valid check for emb status clear*/
#define IS_VALID_EMB_STATUS_CLR(x) \
( (EMBPortInFlagClr == (x)) || \
(EMBPWMSameFlagCLr == (x)) || \
(EMBCmpFlagClr == (x)) || \
(EMBOSCFailFlagCLr == (x)))
/*!< Parameter valid check for emb irq enable*/
#define IS_VALID_EMB_IRQ(x) \
( (PORTBrkIrq == (x)) || \
(PWMSmBrkIrq == (x)) || \
(CMPBrkIrq == (x)) || \
(OSCFailBrkIrq == (x)))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/*******************************************************************************
* \brief EMB interrupt request enable or disable
*
* \param [in] EMBx EMB unit
* \param [in] enEMBIrq Irq type
* \param [in] bEn true/false
*
* \retval en_result_t Ok: config success
******************************************************************************/
en_result_t EMB_ConfigIrq(M4_EMB_TypeDef *EMBx,
en_emb_irq_type_t enEMBIrq,
bool bEn)
{
en_result_t enRet = ErrorInvalidParameter;
if (IS_VALID_EMB_UNIT(EMBx))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_EMB_IRQ(enEMBIrq));
enRet = Ok;
switch (enEMBIrq)
{
case PORTBrkIrq:
EMBx->INTEN_f.PORTINTEN = (uint32_t)bEn;
break;
case PWMSmBrkIrq:
EMBx->INTEN_f.PWMINTEN = (uint32_t)bEn;
break;
case CMPBrkIrq:
EMBx->INTEN_f.CMPINTEN = (uint32_t)bEn;
break;
case OSCFailBrkIrq:
EMBx->INTEN_f.OSINTEN = (uint32_t)bEn;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Get EMB status
**
** \param [in] EMBx EMB unit
**
** \param [in] enStatus EMB status type
**
** \retval EMB status
**
******************************************************************************/
bool EMB_GetStatus(M4_EMB_TypeDef *EMBx, en_emb_status_t enStatus)
{
bool status = false;
/* Check parameters */
DDL_ASSERT(IS_VALID_EMB_UNIT(EMBx));
DDL_ASSERT(IS_VALID_EMB_STATUS_TYPE(enStatus));
switch (enStatus)
{
case EMBFlagPortIn:
status = EMBx->STAT_f.PORTINF;
break;
case EMBFlagPWMSame:
status = EMBx->STAT_f.PWMSF;
break;
case EMBFlagCmp:
status = EMBx->STAT_f.CMPF;
break;
case EMBFlagOSCFail:
status = EMBx->STAT_f.OSF;
break;
case EMBPortInState:
status = EMBx->STAT_f.PORTINST;
break;
case EMBPWMState:
status = EMBx->STAT_f.PWMST;
break;
default:
break;
}
return status;
}
/**
*******************************************************************************
** \brief EMB clear status(Recover from protection state)
**
** \param [in] EMBx EMB unit
**
** \param [in] enStatusClr EMB status clear type
**
** \retval en_result_t Ok: Config Success
**
******************************************************************************/
en_result_t EMB_ClrStatus(M4_EMB_TypeDef *EMBx,
en_emb_status_clr_t enStatusClr)
{
en_result_t enRet = ErrorInvalidParameter;
if (IS_VALID_EMB_UNIT(EMBx))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_EMB_STATUS_CLR(enStatusClr));
enRet = Ok;
switch (enStatusClr)
{
case EMBPortInFlagClr:
EMBx->STATCLR_f.PORTINFCLR = 1ul;
break;
case EMBPWMSameFlagCLr:
EMBx->STATCLR_f.PWMSFCLR = 1ul;
break;
case EMBCmpFlagClr:
EMBx->STATCLR_f.CMPFCLR = 1ul;
break;
case EMBOSCFailFlagCLr:
EMBx->STATCLR_f.OSFCLR = 1ul;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
return enRet;
}
/*******************************************************************************
* \brief EMB Control Register(CR) for timer6
*
* \param [in] EMBx EMB unit
* \param [in] pstcEMBConfigCR EMB Config CR pointer
*
* \retval en_result_t Ok: Set successfully
* \retval en_result_t ErrorInvalidParameter: Provided parameter is not valid
******************************************************************************/
en_result_t EMB_Config_CR_Timer6(const stc_emb_ctrl_timer6_t* pstcEMBConfigCR)
{
uint32_t u32Val = 0ul;
en_result_t enRet = ErrorInvalidParameter;
if (NULL != pstcEMBConfigCR)
{
if (pstcEMBConfigCR->bEnPortBrake)
{
u32Val |= 1ul;
}
if (pstcEMBConfigCR->bEnCmp1Brake)
{
u32Val |= 1ul << 1;
}
if (pstcEMBConfigCR->bEnCmp2Brake)
{
u32Val |= 1ul << 2;
}
if (pstcEMBConfigCR->bEnCmp3Brake)
{
u32Val |= 1ul << 3;
}
if (pstcEMBConfigCR->bEnOSCFailBrake)
{
u32Val |= 1ul << 5;
}
if (pstcEMBConfigCR->bEnTimer61PWMSBrake)
{
u32Val |= 1ul << 6;
}
if (pstcEMBConfigCR->bEnTimer62PWMSBrake)
{
u32Val |= 1ul << 7;
}
if (pstcEMBConfigCR->bEnTimer63PWMSBrake)
{
u32Val |= 1ul << 8;
}
if (EMBPortFltDiv0 == pstcEMBConfigCR->enPortInFltClkSel)
{
}
if (EMBPortFltDiv8 == pstcEMBConfigCR->enPortInFltClkSel)
{
u32Val |= 1ul << 28;
}
if (EMBPortFltDiv32 == pstcEMBConfigCR->enPortInFltClkSel)
{
u32Val |= 2ul << 28;
}
if (EMBPortFltDiv128 == pstcEMBConfigCR->enPortInFltClkSel)
{
u32Val |= 3ul << 28;
}
if (pstcEMBConfigCR->bEnPorInFlt)
{
u32Val |= 1ul << 30;
}
if (pstcEMBConfigCR->bEnPortInLevelSel_Low)
{
u32Val |= 1ul << 31;
}
M4_EMB1->CTL = u32Val;
enRet = Ok;
}
return enRet;
}
/*******************************************************************************
* \brief EMB Control Register(CR) for timer4
*
* \param [in] EMBx EMB unit
* \param [in] pstcEMBConfigCR EMB Config CR pointer
*
* \retval en_result_t Ok: Set successfully
* \retval en_result_t ErrorInvalidParameter: Provided parameter is not valid
******************************************************************************/
en_result_t EMB_Config_CR_Timer4(M4_EMB_TypeDef *EMBx,
const stc_emb_ctrl_timer4_t* pstcEMBConfigCR)
{
uint32_t u32Val = 0ul;
en_result_t enRet = ErrorInvalidParameter;
if ((M4_EMB1 != EMBx) && \
(IS_VALID_EMB_UNIT(EMBx)) && \
(NULL != pstcEMBConfigCR))
{
if (pstcEMBConfigCR->bEnPortBrake)
{
u32Val |= 1ul;
}
if (pstcEMBConfigCR->bEnCmp1Brake)
{
u32Val |= 1ul << 1;
}
if (pstcEMBConfigCR->bEnCmp2Brake)
{
u32Val |= 1ul << 2;
}
if (pstcEMBConfigCR->bEnCmp3Brake)
{
u32Val |= 1ul << 3;
}
if (pstcEMBConfigCR->bEnOSCFailBrake)
{
u32Val |= 1ul << 5;
}
if (pstcEMBConfigCR->bEnTimer4xWHLSammeBrake)
{
u32Val |= 1ul << 6;
}
if (pstcEMBConfigCR->bEnTimer4xVHLSammeBrake)
{
u32Val |= 1ul << 7;
}
if (pstcEMBConfigCR->bEnTimer4xUHLSammeBrake)
{
u32Val |= 1ul << 8;
}
if (EMBPortFltDiv0 == pstcEMBConfigCR->enPortInFltClkSel)
{
}
if (EMBPortFltDiv8 == pstcEMBConfigCR->enPortInFltClkSel)
{
u32Val |= 1ul << 28;
}
if (EMBPortFltDiv32 == pstcEMBConfigCR->enPortInFltClkSel)
{
u32Val |= 2ul << 28;
}
if (EMBPortFltDiv128 == pstcEMBConfigCR->enPortInFltClkSel)
{
u32Val |= 3ul << 28;
}
if (pstcEMBConfigCR->bEnPorInFlt)
{
u32Val |= 1ul << 30;
}
if (pstcEMBConfigCR->bEnPortInLevelSel_Low)
{
u32Val |= 1ul << 31;
}
EMBx->CTL = u32Val;
enRet = Ok;
}
return enRet;
}
/*******************************************************************************
* \brief EMB detect PWM atcive level (short detection) selection for timer6
*
* \param [in] EMBx EMB unit
* \param [in] pstcEMBPWMlv EMB en detect active level pointer
*
* \retval en_result_t Ok: Set successfully
* \retval en_result_t ErrorInvalidParameter: Provided parameter is not valid
******************************************************************************/
en_result_t EMB_PWMLv_Timer6(const stc_emb_pwm_level_timer6_t* pstcEMBPWMlv)
{
uint32_t u32Val = 0ul;
en_result_t enRet = ErrorInvalidParameter;
if (NULL != pstcEMBPWMlv)
{
if (pstcEMBPWMlv->bEnTimer61HighLevelDect)
{
u32Val |= 0x1ul;
}
if (pstcEMBPWMlv->bEnTimer62HighLevelDect)
{
u32Val |= 0x2ul;
}
if (pstcEMBPWMlv->bEnTimer63HighLevelDect)
{
u32Val |= 0x4ul;
}
M4_EMB1->PWMLV = u32Val;
enRet = Ok;
}
return enRet;
}
/*******************************************************************************
* \brief EMB detect PWM atcive level (short detection) selection for timer4
*
* \param [in] EMBx EMB unit
* \param [in] pstcEMBPWMlv EMB en detect active level pointer
*
* \retval en_result_t Ok: Set successfully
* \retval en_result_t ErrorInvalidParameter: Provided parameter is not valid
******************************************************************************/
en_result_t EMB_PWMLv_Timer4(M4_EMB_TypeDef *EMBx,
const stc_emb_pwm_level_timer4_t* pstcEMBPWMlv)
{
uint32_t u32Val = 0ul;
en_result_t enRet = ErrorInvalidParameter;
if ((IS_VALID_EMB_UNIT(EMBx)) && \
(M4_EMB1 != EMBx) && \
(NULL != pstcEMBPWMlv))
{
if (pstcEMBPWMlv->bEnWHLphaseHighLevelDect)
{
u32Val |= 0x1ul;
}
if (pstcEMBPWMlv->bEnVHLPhaseHighLevelDect)
{
u32Val |= 0x2ul;
}
if (pstcEMBPWMlv->bEnUHLPhaseHighLevelDect)
{
u32Val |= 0x4ul;
}
EMBx->PWMLV = u32Val;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief EMB Software brake
**
** \param [in] EMBx EMB unit
**
** \param [in] bEn true: Software Brake Enable / false: Software Brake Disable
**
** \retval en_result_t Ok: Config Success
**
******************************************************************************/
en_result_t EMB_SwBrake(M4_EMB_TypeDef *EMBx, bool bEn)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_EMB_UNIT(EMBx));
EMBx->SOE_f.SOE = (uint32_t)bEn;
return Ok;
}
//@} // EMBGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,464 @@
/******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_event_port.c
**
** A detailed description is available at
** @link EventPortGroup EventPort description @endlink
**
** - 2018-12-07 CDT First version for Device Driver Library of EventPort.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_event_port.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup EventPortGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define EP1_BASE 0x40010800ul + 0x0100ul
#define EP2_BASE 0x40010800ul + 0x011Cul
#define EP3_BASE 0x40010800ul + 0x0138ul
#define EP4_BASE 0x40010800ul + 0x0154ul
#define EP1_DIR_BASE 0x00ul
#define EP1_IDR_BASE 0x04ul
#define EP1_ODR_BASE 0x08ul
#define EP1_ORR_BASE 0x0Cul
#define EP1_OSR_BASE 0x10ul
#define EP1_RISR_BASE 0x14ul
#define EP1_FAL_BASE 0x18ul
#define EP_NFCR_BASE 0x40010800ul + 0x0170ul
/*! Parameter validity check for port group. */
#define IS_VALID_EVENT_PORT(x) \
( ((x) == EventPort1) || \
((x) == EventPort2) || \
((x) == EventPort3) || \
((x) == EventPort4))
/*! Parameter validity check for pin. */
#define IS_VALID_EVENT_PIN(x) \
( ((x) == EventPin00) || \
((x) == EventPin01) || \
((x) == EventPin02) || \
((x) == EventPin03) || \
((x) == EventPin04) || \
((x) == EventPin05) || \
((x) == EventPin06) || \
((x) == EventPin07) || \
((x) == EventPin08) || \
((x) == EventPin09) || \
((x) == EventPin10) || \
((x) == EventPin11) || \
((x) == EventPin12) || \
((x) == EventPin13) || \
((x) == EventPin14) || \
((x) == EventPin15))
/*! Parameter valid check for Event Port common trigger. */
#define IS_EP_COM_TRIGGER(x) \
( ((x) == EpComTrigger_1) || \
((x) == EpComTrigger_2) || \
((x) == EpComTrigger_1_2))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Event Port init
**
** \param [in] enEventPort Event port index, This parameter can be
** any value of @ref en_event_port_t
** \param [in] u16EventPin Event pin index, This parameter can be
** any composed value of @ref en_event_pin_t
** \param [in] pstcEventPortInit Structure pointer of event port configuration
**
** \retval Ok Init successful
** ErrorInvalidParameter Event port index invalid
**
******************************************************************************/
en_result_t EVENTPORT_Init(en_event_port_t enEventPort, uint16_t u16EventPin, \
const stc_event_port_init_t *pstcEventPortInit)
{
en_result_t enRet = Ok;
uint32_t *EPDIRx; ///< Direction register
uint32_t *EPORRx; ///< Reset after trigger enable register
uint32_t *EPOSRx; ///< Set after trigger enable register
uint32_t *EPRISRx; ///< Rising edge detect enable register
uint32_t *EPFALx; ///< Falling edge detect enable register
EPDIRx = (uint32_t *)(EP1_BASE + EP1_DIR_BASE + (0x1C * enEventPort));
EPORRx = (uint32_t *)(EP1_BASE + EP1_ORR_BASE + (0x1C * enEventPort));
EPOSRx = (uint32_t *)(EP1_BASE + EP1_OSR_BASE + (0x1C * enEventPort));
EPRISRx= (uint32_t *)(EP1_BASE + EP1_RISR_BASE+ (0x1C * enEventPort));
EPFALx = (uint32_t *)(EP1_BASE + EP1_FAL_BASE + (0x1C * enEventPort));
/* Direction configure */
if (EventPortOut == pstcEventPortInit->enDirection)
{
*EPDIRx |= u16EventPin;
}
else
{
*EPDIRx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
}
/* Reset if be triggered */
if (Enable == pstcEventPortInit->enReset)
{
*EPORRx |= u16EventPin;
}
else
{
*EPORRx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
}
/* Set if be triggered */
if (Enable == pstcEventPortInit->enSet)
{
*EPOSRx |= u16EventPin;
}
else
{
*EPOSRx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
}
/* Rising edge detect setting */
if (Enable == pstcEventPortInit->enRisingDetect)
{
*EPRISRx |= u16EventPin;
}
else
{
*EPRISRx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
}
/* Falling edge detect setting */
if (Enable == pstcEventPortInit->enFallingDetect)
{
*EPFALx |= u16EventPin;
}
else
{
*EPFALx &= (~(uint32_t)u16EventPin) & 0xFFFFul;
}
/* Noise filter setting */
switch (enEventPort)
{
case EventPort1:
M4_AOS->PEVNTNFCR_f.NFEN1 = pstcEventPortInit->enFilter;
M4_AOS->PEVNTNFCR_f.DIVS1 = pstcEventPortInit->enFilterClk;
break;
case EventPort2:
M4_AOS->PEVNTNFCR_f.NFEN2 = pstcEventPortInit->enFilter;
M4_AOS->PEVNTNFCR_f.DIVS2 = pstcEventPortInit->enFilterClk;
break;
case EventPort3:
M4_AOS->PEVNTNFCR_f.NFEN3 = pstcEventPortInit->enFilter;
M4_AOS->PEVNTNFCR_f.DIVS3 = pstcEventPortInit->enFilterClk;
break;
case EventPort4:
M4_AOS->PEVNTNFCR_f.NFEN4 = pstcEventPortInit->enFilter;
M4_AOS->PEVNTNFCR_f.DIVS4 = pstcEventPortInit->enFilterClk;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
return enRet;
}
/**
*******************************************************************************
** \brief Event Port de-init, restore all registers to default value
**
** \param None
**
** \retval Ok De-init successful
**
******************************************************************************/
en_result_t EVENTPORT_DeInit(void)
{
uint32_t EPDIRx ;
uint32_t EPODRx ;
uint32_t EPORRx ;
uint32_t EPOSRx ;
uint32_t EPRISRx;
uint32_t EPFALx ;
uint8_t u8EPCnt;
EPDIRx = (uint32_t)(EP1_BASE + EP1_DIR_BASE);
EPODRx = (uint32_t)(EP1_BASE + EP1_ODR_BASE);
EPORRx = (uint32_t)(EP1_BASE + EP1_ORR_BASE);
EPOSRx = (uint32_t)(EP1_BASE + EP1_OSR_BASE);
EPRISRx = (uint32_t)(EP1_BASE + EP1_RISR_BASE);
EPFALx = (uint32_t)(EP1_BASE + EP1_FAL_BASE);
/* Restore all registers to default value */
M4_AOS->PEVNTTRGSR12 = 0x1FFul;
M4_AOS->PEVNTTRGSR34 = 0x1FFul;
M4_AOS->PEVNTNFCR = 0ul;
for (u8EPCnt = 0u; u8EPCnt < 4u; u8EPCnt++)
{
*(uint32_t *)(EPDIRx + 0x1Cul * u8EPCnt) = 0ul;
*(uint32_t *)(EPODRx + 0x1Cul * u8EPCnt) = 0ul;
*(uint32_t *)(EPORRx + 0x1Cul * u8EPCnt) = 0ul;
*(uint32_t *)(EPOSRx + 0x1Cul * u8EPCnt) = 0ul;
*(uint32_t *)(EPRISRx + 0x1Cul * u8EPCnt) = 0ul;
*(uint32_t *)(EPFALx + 0x1Cul * u8EPCnt) = 0ul;
}
return Ok;
}
/**
*******************************************************************************
** \brief Event Port trigger source select
**
** \param [in] enEventPort Event port index, This parameter can be
** any value of @ref en_event_port_t
** \param [in] enTriggerSrc Event port trigger source. This parameter
** can be any value of @ref en_event_src_t
** \retval Ok Trigger source is set
** ErrorInvalidParameter Invalid event port enum
**
******************************************************************************/
en_result_t EVENTPORT_SetTriggerSrc(en_event_port_t enEventPort, \
en_event_src_t enTriggerSrc)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_EVENT_PORT(enEventPort));
if ((EventPort1 == enEventPort) || (EventPort2 == enEventPort))
{
M4_AOS->PEVNTTRGSR12 = enTriggerSrc;
}
else if ((EventPort3 == enEventPort) || (EventPort4 == enEventPort))
{
M4_AOS->PEVNTTRGSR34 = enTriggerSrc;
}
else
{
enRet = ErrorInvalidParameter;
}
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable Event Port common trigger.
**
** \param [in] enEventPort Event port index, This parameter can be
** any value of @ref en_event_port_t
** \param [in] enComTrigger Event port common trigger selection.
** See @ref en_event_port_com_trigger_t for details.
** \param [in] enState Enable or disable the specified common trigger.
**
** \retval None.
**
******************************************************************************/
void EVENTPORT_ComTriggerCmd(en_event_port_t enEventPort, \
en_event_port_com_trigger_t enComTrigger, \
en_functional_state_t enState)
{
uint32_t u32ComTrig = (uint32_t)enComTrigger;
__IO uint32_t *TRGSELx;
TRGSELx = (__IO uint32_t *)((uint32_t)&M4_AOS->PEVNTTRGSR12 + (4UL * ((uint32_t)enEventPort/2UL)));
if (NULL != TRGSELx)
{
DDL_ASSERT(IS_EP_COM_TRIGGER(enComTrigger));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
if (enState == Enable)
{
*TRGSELx |= (u32ComTrig << 30u);
}
else
{
*TRGSELx &= ~(u32ComTrig << 30u);
}
}
}
/**
*******************************************************************************
** \brief Read Event Port value after be triggered
**
** \param [in] enEventPort Event port index, This parameter can be
** any value of @ref en_event_port_t
**
** \retval uint16_t The output port value
**
******************************************************************************/
uint16_t EVENTPORT_GetData(en_event_port_t enEventPort)
{
uint16_t u16Data = 0u;
DDL_ASSERT(IS_VALID_EVENT_PORT(enEventPort));
switch (enEventPort)
{
case EventPort1:
u16Data = (uint16_t)(M4_AOS->PEVNTIDR1 & 0xFFFFul);
break;
case EventPort2:
u16Data = (uint16_t)(M4_AOS->PEVNTIDR2 & 0xFFFFul);
break;
case EventPort3:
u16Data = (uint16_t)(M4_AOS->PEVNTIDR3 & 0xFFFFul);
break;
case EventPort4:
u16Data = (uint16_t)(M4_AOS->PEVNTIDR4 & 0xFFFFul);
break;
}
return u16Data;
}
/**
*******************************************************************************
** \brief Read Event Pin value after triggered
**
** \param [in] enEventPort Event port index, This parameter can be
** any value of @ref en_event_port_t
** \param [in] enEventPin GPIO pin index, This parameter can be
** any value of @ref en_event_pin_t
** \retval en_flag_status_t The output port pin value
**
******************************************************************************/
en_flag_status_t EVENTPORT_GetBit(en_event_port_t enEventPort, en_event_pin_t enEventPin)
{
bool bBitValue = false;
switch (enEventPort)
{
case EventPort1:
bBitValue = M4_AOS->PEVNTIDR1 & enEventPin;
break;
case EventPort2:
bBitValue = M4_AOS->PEVNTIDR2 & enEventPin;
break;
case EventPort3:
bBitValue = M4_AOS->PEVNTIDR3 & enEventPin;
break;
case EventPort4:
bBitValue = M4_AOS->PEVNTIDR4 & enEventPin;
break;
}
return (en_flag_status_t)(bool)((!!bBitValue));
}
/**
*******************************************************************************
** \brief Set Event Port Pin
**
** \param [in] enEventPort Event port index, This parameter can be
** any value of @ref en_event_port_t
** \param [in] u16EventPin Event pin index, This parameter can be
** any composed value of @ref en_event_pin_t
** \retval Ok Set successful
** ErrorInvalidParameter Event port index invalid
**
******************************************************************************/
en_result_t EVENTPORT_SetBits(en_event_port_t enEventPort, en_event_pin_t u16EventPin)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_EVENT_PORT(enEventPort));
switch (enEventPort)
{
case EventPort1:
M4_AOS->PEVNTODR1 |= u16EventPin;
break;
case EventPort2:
M4_AOS->PEVNTODR2 |= u16EventPin;
break;
case EventPort3:
M4_AOS->PEVNTODR3 |= u16EventPin;
break;
case EventPort4:
M4_AOS->PEVNTODR4 |= u16EventPin;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
return enRet;
}
/**
*******************************************************************************
** \brief Reset Event Port Pin
**
** \param [in] enEventPort Event port index, This parameter can be
** any value of @ref en_event_port_t
** \param [in] u16EventPin Event pin index, This parameter can be
** any composed value of @ref en_event_pin_t
** \retval Ok Reset successful
** ErrorInvalidParameter Event port index invalid
**
******************************************************************************/
en_result_t EVENTPORT_ResetBits(en_event_port_t enEventPort, en_event_pin_t u16EventPin)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_EVENT_PORT(enEventPort));
switch (enEventPort)
{
case EventPort1:
M4_AOS->PEVNTODR1 &= (~(uint32_t)u16EventPin) & 0xFFFFul;
break;
case EventPort2:
M4_AOS->PEVNTODR2 &= (~(uint32_t)u16EventPin) & 0xFFFFul;
break;
case EventPort3:
M4_AOS->PEVNTODR3 &= (~(uint32_t)u16EventPin) & 0xFFFFul;
break;
case EventPort4:
M4_AOS->PEVNTODR4 &= (~(uint32_t)u16EventPin) & 0xFFFFul;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
return enRet;
}
//@} // EventPortGroup
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/

View File

@@ -0,0 +1,333 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_exint_nmi_swi.c
**
** A detailed description is available at
** @link ExintNmiSwiGroup Exint/Nmi/Swi description @endlink
**
** - 2018-10-17 CDT First version for Device Driver Library of exint, Nmi, SW interrupt.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_exint_nmi_swi.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup ExintNmiSwiGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*! Parameter validity check for external interrupt channel. */
#define IS_VALID_CH(x) \
( ((x) == ExtiCh00) || \
((x) == ExtiCh01) || \
((x) == ExtiCh02) || \
((x) == ExtiCh03) || \
((x) == ExtiCh04) || \
((x) == ExtiCh05) || \
((x) == ExtiCh06) || \
((x) == ExtiCh07) || \
((x) == ExtiCh08) || \
((x) == ExtiCh09) || \
((x) == ExtiCh10) || \
((x) == ExtiCh11) || \
((x) == ExtiCh12) || \
((x) == ExtiCh13) || \
((x) == ExtiCh14) || \
((x) == ExtiCh15))
/*! Parameter validity check for null pointer. */
#define IS_NULL_POINT(x) (NULL != (x))
/*! Parameter validity check for external interrupt trigger method. */
#define IS_VALID_LEVEL(x) \
( ((x) == ExIntLowLevel) || \
((x) == ExIntBothEdge) || \
((x) == ExIntRisingEdge) || \
((x) == ExIntFallingEdge))
/*! Parameter validity check for NMI interrupt source. */
#define IS_VALID_NMI_SRC(x) \
( ((x) == NmiSrcNmi) || \
((x) == NmiSrcSwdt) || \
((x) == NmiSrcVdu1) || \
((x) == NmiSrcVdu2) || \
((x) == NmiSrcXtalStop) || \
((x) == NmiSrcSramPE) || \
((x) == NmiSrcSramDE) || \
((x) == NmiSrcMpu) || \
((x) == NmiSrcWdt))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
static func_ptr_t pfnNmiCallback;
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief External Int initialization
**
** \param [in] pstcExtiConfig EXTI configure structure
**
** \retval Ok EXTI initialized
**
******************************************************************************/
en_result_t EXINT_Init(const stc_exint_config_t *pstcExtiConfig)
{
stc_intc_eirqcr_field_t *EIRQCRx;
DDL_ASSERT(IS_VALID_CH(pstcExtiConfig->enExitCh));
EIRQCRx = (stc_intc_eirqcr_field_t *)((uint32_t)(&M4_INTC->EIRQCR0) + \
(uint32_t)(4ul * (uint32_t)(pstcExtiConfig->enExitCh)));
/* Set filter function */
EIRQCRx->EFEN = pstcExtiConfig->enFilterEn;
EIRQCRx->EISMPCLK = pstcExtiConfig->enFltClk;
/* Set detection level */
EIRQCRx->EIRQTRG = pstcExtiConfig->enExtiLvl;
return Ok;
}
/**
*******************************************************************************
** \brief Get External interrupt request flag
**
** \param [in] enExint NMI Int source, This parameter can be
** any value of @ref en_exti_ch_t
**
** \retval Set Corresponding Ex.Int request flag be set
** Reset Corresponding Ex.Int request flag not be set
**
******************************************************************************/
en_int_status_t EXINT_IrqFlgGet(en_exti_ch_t enExint)
{
en_int_status_t enRet;
DDL_ASSERT(IS_VALID_CH(enExint));
enRet = (1u == !!(M4_INTC->EIFR & (1ul<<enExint)) ? Set : Reset);
return enRet;
}
/**
*******************************************************************************
** \brief Clear External interrupt request flag
**
** \param [in] enExint Ext. interrupt channel, This parameter can be
** any value of @ref en_exti_ch_t
**
** \retval Ok Interrupt source be cleared
**
******************************************************************************/
en_result_t EXINT_IrqFlgClr(en_exti_ch_t enExint)
{
M4_INTC->EICFR |= (uint32_t)(1ul << enExint);
return Ok;
}
/**
*******************************************************************************
** \brief NMI initialization
**
** \param [in] pstcNmiConfig NMI configure structure
**
** \retval Ok NMI initialized
** ErrorInvalidParameter NMI configuration pointer is null
**
******************************************************************************/
en_result_t NMI_Init(const stc_nmi_config_t *pstcNmiConfig)
{
en_result_t enRet = ErrorInvalidParameter;
if (NULL != pstcNmiConfig)
{
/* NMI callback function */
pfnNmiCallback = pstcNmiConfig->pfnNmiCallback;
/* Set filter function */
M4_INTC->NMICR_f.NFEN = pstcNmiConfig->enFilterEn;
/* Set filter clock */
M4_INTC->NMICR_f.NSMPCLK = pstcNmiConfig->enFilterClk;
/* Set detection level */
M4_INTC->NMICR_f.NMITRG = pstcNmiConfig->enNmiLvl;
/* Set NMI source */
M4_INTC->NMIENR = (uint32_t)pstcNmiConfig->u16NmiSrc;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief De-Init Non-Maskable Interrupt (NMI)
**
** \param None
**
** \retval Ok NMI De-initialized
**
******************************************************************************/
en_result_t NMI_DeInit(void)
{
/* Set internal data */
pfnNmiCallback = NULL;
/* clear NMI control register */
M4_INTC->NMICR = 0u;
/* clear NMI enable register */
M4_INTC->NMIENR = 0u;
/* clear all NMI flags */
M4_INTC->NMIFR = 0u;
return Ok;
}
/**
*******************************************************************************
** \brief Get NMI interrupt request flag
**
** \param [in] enNmiSrc NMI Int source, This parameter can be
** any value of @ref en_nmi_src_t
**
** \retval Set Corresponding NMI flag be set
** Reset Corresponding NMI flag not be set
**
******************************************************************************/
en_int_status_t NMI_IrqFlgGet(en_nmi_src_t enNmiSrc)
{
DDL_ASSERT(IS_VALID_NMI_SRC(enNmiSrc));
en_int_status_t enRet = Reset;
switch (enNmiSrc)
{
case NmiSrcNmi:
enRet = (en_int_status_t)(M4_INTC->NMIFR_f.NMIFR);
break;
case NmiSrcSwdt:
enRet = (en_int_status_t)(M4_INTC->NMIFR_f.SWDTFR);
break;
case NmiSrcVdu1:
enRet = (en_int_status_t)(M4_INTC->NMIFR_f.PVD1FR);
break;
case NmiSrcVdu2:
enRet = (en_int_status_t)(M4_INTC->NMIFR_f.PVD2FR);
break;
case NmiSrcXtalStop:
enRet = (en_int_status_t)(M4_INTC->NMIFR_f.XTALSTPFR);
break;
case NmiSrcSramPE:
enRet = (en_int_status_t)(M4_INTC->NMIFR_f.REPFR);
break;
case NmiSrcSramDE:
enRet = (en_int_status_t)(M4_INTC->NMIFR_f.RECCFR);
break;
case NmiSrcMpu:
enRet = (en_int_status_t)(M4_INTC->NMIFR_f.BUSMFR);
break;
case NmiSrcWdt:
enRet = (en_int_status_t)(M4_INTC->NMIFR_f.WDTFR);
break;
default:
break;
}
return enRet;
}
/**
*******************************************************************************
** \brief Clear NMI interrupt request flag
**
** \param [in] u16NmiSrc NMI Int source, This parameter can be
** any composited value of @ref en_nmi_src_t
**
** \retval Ok Interrupt source be cleared
**
******************************************************************************/
en_result_t NMI_IrqFlgClr(uint16_t u16NmiSrc)
{
M4_INTC->NMICFR |= u16NmiSrc;
return Ok;
}
/**
*******************************************************************************
** \brief ISR for NMI
**
******************************************************************************/
void NMI_IrqHandler(void)
{
DDL_ASSERT(IS_NULL_POINT(pfnNmiCallback));
pfnNmiCallback();
}
/**
*******************************************************************************
** \brief Enable Softeware Interrupt (SWI)
**
* \param [in] u32SwiCh This parameter can be any composited
* value of @ref en_swi_ch_t
**
** \retval Ok SWI initialized
**
******************************************************************************/
en_result_t SWI_Enable(uint32_t u32SwiCh)
{
M4_INTC->SWIER |= u32SwiCh;
return Ok;
}
/**
*******************************************************************************
** \brief De-Init Softeware Interrupt (SWI)
**
* \param [in] u32SwiCh This parameter can be any composited
* value of @ref en_swi_ch_t
**
** \retval Ok SWI de-initialized
**
******************************************************************************/
en_result_t SWI_Disable(uint32_t u32SwiCh)
{
/* clear software interrupt enable register */
M4_INTC->SWIER &= ~u32SwiCh;
return Ok;
}
//@} // ExintNmiSwiGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,667 @@
/******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_gpio.c
**
** A detailed description is available at
** @link GpioGroup Gpio description @endlink
**
** - 2018-10-12 CDT First version for Device Driver Library of Gpio.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_gpio.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup GpioGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define GPIO_BASE (0x40053800ul)
#define PODR_BASE (0x0004ul)
#define POER_BASE (0x0006ul)
#define POSR_BASE (0x0008ul)
#define PORR_BASE (0x000Aul)
#define PCR_BASE (0x0400ul)
#define PFSR_BASE (0x0402ul)
/*! Parameter validity check for port group. */
#define IS_VALID_PORT(x) \
( ((x) == PortA) || \
((x) == PortB) || \
((x) == PortC) || \
((x) == PortD) || \
((x) == PortE) || \
((x) == PortH))
/*! Parameter validity check for pin. */
#define IS_VALID_PIN(x) \
( ((x) == Pin00) || \
((x) == Pin01) || \
((x) == Pin02) || \
((x) == Pin03) || \
((x) == Pin04) || \
((x) == Pin05) || \
((x) == Pin06) || \
((x) == Pin07) || \
((x) == Pin08) || \
((x) == Pin09) || \
((x) == Pin10) || \
((x) == Pin11) || \
((x) == Pin12) || \
((x) == Pin13) || \
((x) == Pin14) || \
((x) == Pin15))
/*! Parameter validity check for debug pins. */
#define IS_VALID_DEBUGPIN(x) ((x) <= 0x1Fu)
/*! Parameter validity check for pin mode. */
#define IS_VALID_PINMODE(x) \
( ((x) == Pin_Mode_In) || \
((x) == Pin_Mode_Out) || \
((x) == Pin_Mode_Ana))
/*! Parameter validity check for pin drive capacity. */
#define IS_VALID_PINDRV(x) \
( ((x) == Pin_Drv_L) || \
((x) == Pin_Drv_M) || \
((x) == Pin_Drv_H))
/*! Parameter validity check for pin output type. */
#define IS_VALID_PINTYPE(x) \
( ((x) == Pin_OType_Cmos) || \
((x) == Pin_OType_Od))
/*! Parameter validity check for pin read wait cycle. */
#define IS_VALID_READWAIT(x) \
( ((x) == WaitCycle0) || \
((x) == WaitCycle1) || \
((x) == WaitCycle2) || \
((x) == WaitCycle3))
/*! Parameter validity check for pin function */
#define IS_VALID_FUNC(x) \
( ((x) == Func_Gpio) || \
(((x) >= Func_Fcmref) && \
((x) <= Func_I2s)) || \
((x) == Func_Evnpt) || \
((x) == Func_Eventout) || \
(((x) >= Func_Usart1_Tx) && \
((x) <= Func_I2s2_Ck)))
/*! Parameter validity check for pin sub-function */
#define IS_VALID_SUBFUNC(x) \
( ((x) == Func_Gpio) || \
((x) == Func_Fcmref) || \
((x) == Func_Rtcout) || \
((x) == Func_Vcout) || \
((x) == Func_Adtrg) || \
((x) == Func_Mclkout) || \
((x) == Func_Tim4) || \
((x) == Func_Tim6) || \
((x) == Func_Tima0) || \
((x) == Func_Tima1) || \
((x) == Func_Tima2) || \
((x) == Func_Emb) || \
((x) == Func_Usart_Ck) || \
((x) == Func_Spi_Nss) || \
((x) == Func_Qspi) || \
((x) == Func_Key) || \
((x) == Func_Sdio) || \
((x) == Func_I2s) || \
((x) == Func_UsbF) || \
((x) == Func_Evnpt) || \
((x) == Func_Eventout))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Port init
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] u16Pin GPIO pin index, This parameter can be
** any composed value of @ref en_pin_t
** \param [in] pstcPortInit Structure pointer of port configuration
**
** \retval Ok Port initial successful
**
******************************************************************************/
en_result_t PORT_Init(en_port_t enPort, uint16_t u16Pin, const stc_port_init_t *pstcPortInit)
{
stc_port_pcr_field_t *PCRx;
stc_port_pfsr_field_t * PFSRx;
uint8_t u8PinPos = 0u;
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
DDL_ASSERT(IS_VALID_PINMODE(pstcPortInit->enPinMode));
DDL_ASSERT(IS_VALID_PINDRV(pstcPortInit->enPinDrv));
DDL_ASSERT(IS_VALID_PINTYPE(pstcPortInit->enPinOType));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enLatch));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enExInt));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enInvert));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enPullUp));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcPortInit->enPinSubFunc));
PORT_Unlock();
for (u8PinPos = 0u; u8PinPos < 16u; u8PinPos ++)
{
if (u16Pin & (1ul<<u8PinPos))
{
PCRx = (stc_port_pcr_field_t *)((uint32_t)(&M4_PORT->PCRA0) + \
enPort * 0x40ul + u8PinPos * 0x04ul);
PFSRx = (stc_port_pfsr_field_t *)((uint32_t)(&M4_PORT->PFSRA0) + \
enPort * 0x40ul + u8PinPos * 0x04ul);
/* Input latch function setting */
PCRx->LTE = pstcPortInit->enLatch;
/* External interrupt input enable setting */
PCRx->INTE = pstcPortInit->enExInt;
/* In_Out invert setting */
PCRx->INVE = pstcPortInit->enInvert;
/* Pin pull-up setting */
PCRx->PUU = pstcPortInit->enPullUp;
/* CMOS/OD output setting */
PCRx->NOD = pstcPortInit->enPinOType;
/* Pin drive mode setting */
PCRx->DRV = pstcPortInit->enPinDrv;
/* Pin mode setting */
switch (pstcPortInit->enPinMode)
{
case Pin_Mode_In:
PCRx->DDIS = 0u;
PCRx->POUTE = 0u;
break;
case Pin_Mode_Out:
PCRx->DDIS = 0u;
PCRx->POUTE = 1u;
break;
case Pin_Mode_Ana:
PCRx->DDIS = 1u;
break;
default:
break;
}
/* Sub function enable setting */
PFSRx->BFE = pstcPortInit->enPinSubFunc;
}
}
PORT_Lock();
return Ok;
}
/**
*******************************************************************************
** \brief Port de-init
**
** \param None
**
** \retval Ok GPIO de-initial successful
**
******************************************************************************/
en_result_t PORT_DeInit(void)
{
uint8_t u8PortIdx, u8PinIdx;
PORT_Unlock();
for (u8PortIdx = (uint8_t)PortA; u8PortIdx <= (uint8_t)PortH; u8PortIdx++)
{
*(uint16_t *)(GPIO_BASE + PODR_BASE + u8PortIdx * 0x10ul) = 0u;
*(uint16_t *)(GPIO_BASE + POER_BASE + u8PortIdx * 0x10ul) = 0u;
*(uint16_t *)(GPIO_BASE + POSR_BASE + u8PortIdx * 0x10ul) = 0u;
*(uint16_t *)(GPIO_BASE + PORR_BASE + u8PortIdx * 0x10ul) = 0u;
for (u8PinIdx = 0u; u8PinIdx < 16u; u8PinIdx++)
{
if (((uint8_t)PortH == u8PortIdx) && (3u == u8PinIdx))
{
break;
}
*(uint16_t *)(GPIO_BASE + PCR_BASE + u8PortIdx * 0x40ul + u8PinIdx * 0x4ul) = 0u;
*(uint16_t *)(GPIO_BASE + PFSR_BASE + u8PortIdx * 0x40ul + u8PinIdx * 0x4ul) = 0u;
}
}
M4_PORT->PCCR = 0u;
M4_PORT->PINAER = 0u;
M4_PORT->PSPCR = 0x1Fu;
PORT_Lock();
return Ok;
}
/**
*******************************************************************************
** \brief Special control register Setting
**
** \param [in] u8DebugPort Debug port setting register, This parameter
** can be any composed value of @ref en_debug_port_t
**
** \param [in] enFunc The new state of the debug ports.
** \arg Enable Enable.
** \arg Disable Disable.
**
** \retval Ok Debug port set successful
**
******************************************************************************/
en_result_t PORT_DebugPortSetting(uint8_t u8DebugPort, en_functional_state_t enFunc)
{
/* parameter check */
DDL_ASSERT(IS_VALID_DEBUGPIN(u8DebugPort));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enFunc));
PORT_Unlock();
if (Enable == enFunc)
{
M4_PORT->PSPCR |= (uint16_t)(u8DebugPort & 0x1Ful);
}
else
{
M4_PORT->PSPCR &= (uint16_t)(~(u8DebugPort & 0x1Ful));
}
PORT_Lock();
return Ok;
}
/**
*******************************************************************************
** \brief Port Public Setting
**
** \param [in] pstcPortPubSet Structure pointer of public setting (PCCR)
**
** \retval Ok Port public register set successful
**
******************************************************************************/
en_result_t PORT_PubSetting(const stc_port_pub_set_t *pstcPortPubSet)
{
DDL_ASSERT(IS_VALID_FUNC(pstcPortPubSet->enSubFuncSel));
DDL_ASSERT(IS_VALID_READWAIT(pstcPortPubSet->enReadWait));
PORT_Unlock();
/* PCCR setting */
/* Sub function setting */
M4_PORT->PCCR_f.BFSEL = pstcPortPubSet->enSubFuncSel;
/* PIDRx, PCRxy read wait cycle setting */
M4_PORT->PCCR_f.RDWT = pstcPortPubSet->enReadWait;
PORT_Lock();
return Ok;
}
/**
*******************************************************************************
** \brief PSPCR, PCCR, PINAER, PCRxy, PFSRxy write enable
**
** \param None
**
** \retval None
**
******************************************************************************/
void PORT_Unlock(void)
{
M4_PORT->PWPR = 0xA501u;
}
/**
*******************************************************************************
** \brief SPCR, PCCR, PINAER, PCRxy, PFSRxy write disable
**
** \param None
**
** \retval None
**
******************************************************************************/
void PORT_Lock(void)
{
M4_PORT->PWPR = 0xA500u;
}
/**
*******************************************************************************
** \brief Read Port value
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
**
** \retval uint16_t The output port value
**
******************************************************************************/
uint16_t PORT_GetData(en_port_t enPort)
{
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
uint32_t *PIDRx;
PIDRx = (uint32_t *)((uint32_t)(&M4_PORT->PIDRA) + 0x10u * enPort);
return (uint16_t)(*PIDRx);
}
/**
*******************************************************************************
** \brief Read Pin value
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] enPin GPIO pin index, This parameter can be
** any value of @ref en_pin_t
** \retval en_flag_status_t The output port pin value
**
******************************************************************************/
en_flag_status_t PORT_GetBit(en_port_t enPort, en_pin_t enPin)
{
uint32_t *PIDRx;
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
DDL_ASSERT(IS_VALID_PIN(enPin));
PIDRx = (uint32_t *)((uint32_t)(&M4_PORT->PIDRA) + 0x10u * enPort);
return (en_flag_status_t)((bool)(!!(*PIDRx & (enPin))));
}
/**
*******************************************************************************
** \brief Set Port value
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] u16Pin GPIO pin index, This parameter can be
** any composed value of @ref en_pin_t
**
** \retval Ok Data be set to corresponding port
**
******************************************************************************/
en_result_t PORT_SetPortData(en_port_t enPort, uint16_t u16Pin)
{
uint16_t *PODRx;
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
PODRx = (uint16_t *)((uint32_t)(&M4_PORT->PODRA) + 0x10u * enPort);
*PODRx |= u16Pin;
return Ok;
}
/**
*******************************************************************************
** \brief Set Port value
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] u16Pin GPIO pin index, This parameter can be
** any composed value of @ref en_pin_t
**
** \retval Ok Data be reset to corresponding port
**
******************************************************************************/
en_result_t PORT_ResetPortData(en_port_t enPort, uint16_t u16Pin)
{
uint16_t *PODRx;
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
PODRx = (uint16_t *)((uint32_t)(&M4_PORT->PODRA) + 0x10u * enPort);
*PODRx &= (uint16_t)(~u16Pin);
return Ok;
}
/**
*******************************************************************************
** \brief Port Pin Output enable
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] u16Pin GPIO pin index, This parameter can be
** any composed value of @ref en_pin_t
** \param [in] enNewState The new state of pin direction setting
** \retval Ok Set successful to corresponding port/pin
**
******************************************************************************/
en_result_t PORT_OE(en_port_t enPort, uint16_t u16Pin, en_functional_state_t enNewState)
{
uint16_t *POERx;
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
POERx = (uint16_t *)((uint32_t)(&M4_PORT->POERA) + 0x10ul * enPort);
if (Enable == enNewState)
{
*POERx |= u16Pin;
}
else
{
*POERx &= (uint16_t)(~u16Pin);
}
return Ok;
}
/**
*******************************************************************************
** \brief Set Port Pin
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] u16Pin GPIO pin index, This parameter can be
** any composed value of @ref en_pin_t
** \retval Ok Set successful to corresponding pins
**
******************************************************************************/
en_result_t PORT_SetBits(en_port_t enPort, uint16_t u16Pin)
{
uint16_t *POSRx;
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
POSRx = (uint16_t *)((uint32_t)(&M4_PORT->POSRA) + 0x10u * enPort);
*POSRx |= u16Pin;
return Ok;
}
/**
*******************************************************************************
** \brief Reset Port Pin
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] u16Pin GPIO pin index, This parameter can be
** any composed value of @ref en_pin_t
** \retval Ok Set successful to corresponding pins
**
******************************************************************************/
en_result_t PORT_ResetBits(en_port_t enPort, uint16_t u16Pin)
{
uint16_t *PORRx;
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
PORRx = (uint16_t *)((uint32_t)(&M4_PORT->PORRA) + 0x10u * enPort);
*PORRx |= u16Pin;
return Ok;
}
/**
*******************************************************************************
** \brief Toggle Port Pin
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] u16Pin GPIO pin index, This parameter can be
** any composed value of @ref en_pin_t
** \retval Ok Set successful to corresponding pins
**
******************************************************************************/
en_result_t PORT_Toggle(en_port_t enPort, uint16_t u16Pin)
{
uint16_t *POTRx;
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
POTRx = (uint16_t *)((uint32_t)(&M4_PORT->POTRA) + 0x10u * enPort);
*POTRx |= u16Pin;
return Ok;
}
/**
*******************************************************************************
** \brief Set port always ON
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] enNewState The new state of the port always ON function.
** \arg Enable Enable.
** \arg Disable Disable.
**
** \retval Ok Set successful to corresponding pins
**
******************************************************************************/
en_result_t PORT_AlwaysOn(en_port_t enPort, en_functional_state_t enNewState)
{
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
PORT_Unlock();
if (Enable == enNewState)
{
M4_PORT->PINAER |= Enable << (uint8_t)enPort;
}
else
{
M4_PORT->PINAER &= (uint16_t)(~(((1ul << (uint8_t)enPort)) & 0x1Ful));
}
PORT_Lock();
return Ok;
}
/**
*******************************************************************************
** \brief Set Port Pin function
**
** \param [in] enPort GPIO port index, This parameter can be
** any value of @ref en_port_t
** \param [in] u16Pin GPIO pin index, This parameter can be
** any value of @ref en_pin_t
** \param [in] enFuncSel Function selection, This parameter can be
** any value of @ref en_port_func_t
**
** \param [in] enSubFunc The new state of the gpio sub-function.
** \arg Enable Enable.
** \arg Disable Disable.
**
** \retval Ok Set successful to corresponding pins
**
******************************************************************************/
en_result_t PORT_SetFunc(en_port_t enPort, uint16_t u16Pin, en_port_func_t enFuncSel, \
en_functional_state_t enSubFunc)
{
stc_port_pfsr_field_t *PFSRx;
uint8_t u8PinPos = 0u;
/* parameter check */
DDL_ASSERT(IS_VALID_PORT(enPort));
DDL_ASSERT(IS_VALID_FUNC(enFuncSel));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enSubFunc));
PORT_Unlock();
for (u8PinPos = 0u; u8PinPos < 16u; u8PinPos ++)
{
if (u16Pin & (uint16_t)(1ul<<u8PinPos))
{
PFSRx = (stc_port_pfsr_field_t *)((uint32_t)(&M4_PORT->PFSRA0) \
+ 0x40ul * enPort + 0x4ul * u8PinPos);
/* main function setting */
PFSRx->FSEL = enFuncSel;
/* sub function enable setting */
PFSRx->BFE = (Enable == enSubFunc ? Enable : Disable);
}
}
PORT_Lock();
return Ok;
}
/**
*******************************************************************************
** \brief Set global sub-function
**
** \param [in] enFuncSel Function selection, This parameter can be
** some values of @ref en_port_func_t, cannot
** large than 15u
**
** \retval Ok Set successful to corresponding pins
**
******************************************************************************/
en_result_t PORT_SetSubFunc(en_port_func_t enFuncSel)
{
/* parameter check */
DDL_ASSERT(IS_VALID_SUBFUNC(enFuncSel));
PORT_Unlock();
M4_PORT->PCCR_f.BFSEL = enFuncSel;
PORT_Lock();
return Ok;
}
//@} // GpioGroup
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/

View File

@@ -0,0 +1,297 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_hash.c
**
** A detailed description is available at
** @link HashGroup HASH description @endlink
**
** - 2018-10-18 CDT First version for Device Driver Library of HASH.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_hash.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup HashGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* Constants definitions. */
#define HASH_GROUP_LEN (64u)
#define LAST_GROUP_MAX_LEN (56u)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
static void HASH_WriteData(const uint8_t *pu8SrcData);
static void HASH_GetMsgDigest(uint8_t *pu8MsgDigest);
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initialize the HASH.
**
** \param None
**
** \retval None
**
******************************************************************************/
void HASH_Init(void)
{
/* Stop hash calculating */
bM4_HASH_CR_START = 0u;
}
/**
*******************************************************************************
** \brief DeInitialize the HASH.
**
** \param None
**
** \retval None
**
******************************************************************************/
void HASH_DeInit(void)
{
/* Stop hash calculating */
bM4_HASH_CR_START = 0u;
/* Reset register CR. */
M4_HASH->CR = 0u;
}
/**
*******************************************************************************
** \brief HASH(SHA256) processes pu8SrcData.
**
** \param [in] pu8SrcData Pointer to the source data buffer (buffer to
** be hashed).
**
** \param [in] u32SrcDataSize Length of the input buffer in bytes.
**
** \param [out] pu8MsgDigest Pointer to the computed digest. Its size
** must be 32 bytes.
**
** \param [in] u32Timeout Timeout value.
**
** \retval Ok No error occurred.
** \retval ErrorTimeout HASH works timeout.
** \retval ErrorInvalidParameter Parameter error.
**
******************************************************************************/
en_result_t HASH_Start(const uint8_t *pu8SrcData,
uint32_t u32SrcDataSize,
uint8_t *pu8MsgDigest,
uint32_t u32Timeout)
{
en_result_t enRet = ErrorInvalidParameter;
uint8_t u8FillBuffer[HASH_GROUP_LEN];
uint8_t u8FirstGroup = 0u;
uint8_t u8HashEnd = 0u;
uint8_t u8DataEndMark = 0u;
uint32_t u32Index = 0u;
uint32_t u32BitLenHi;
uint32_t u32BitLenLo;
uint32_t u32HashTimeout;
__IO uint32_t u32TimeCount;
if ((NULL != pu8SrcData) &&
(0u != u32SrcDataSize) &&
(NULL != pu8MsgDigest) &&
(0u != u32Timeout))
{
/* 10 is the number of required instructions cycles for the below loop statement. */
u32HashTimeout = u32Timeout * (SystemCoreClock / 10u / 1000u);
u32BitLenHi = (u32SrcDataSize >> 29u) & 0x7u;
u32BitLenLo = (u32SrcDataSize << 3u);
while (1u)
{
/* Stop hash calculating. */
bM4_HASH_CR_START = 0u;
if (u32SrcDataSize >= HASH_GROUP_LEN)
{
HASH_WriteData(&pu8SrcData[u32Index]);
u32SrcDataSize -= HASH_GROUP_LEN;
u32Index += HASH_GROUP_LEN;
}
else if (u32SrcDataSize >= LAST_GROUP_MAX_LEN)
{
memset(u8FillBuffer, 0, HASH_GROUP_LEN);
memcpy(u8FillBuffer, &pu8SrcData[u32Index], u32SrcDataSize);
u8FillBuffer[u32SrcDataSize] = 0x80u;
u8DataEndMark = 1u;
HASH_WriteData(u8FillBuffer);
u32SrcDataSize = 0u;
}
else
{
u8HashEnd = 1u;
}
if (u8HashEnd != 0u)
{
memset(u8FillBuffer, 0, HASH_GROUP_LEN);
if (u32SrcDataSize > 0u)
{
memcpy(u8FillBuffer, &pu8SrcData[u32Index], u32SrcDataSize);
}
if (u8DataEndMark == 0u)
{
u8FillBuffer[u32SrcDataSize] = 0x80u;
}
u8FillBuffer[63u] = (uint8_t)(u32BitLenLo);
u8FillBuffer[62u] = (uint8_t)(u32BitLenLo >> 8u);
u8FillBuffer[61u] = (uint8_t)(u32BitLenLo >> 16u);
u8FillBuffer[60u] = (uint8_t)(u32BitLenLo >> 24u);
u8FillBuffer[59u] = (uint8_t)(u32BitLenHi);
u8FillBuffer[58u] = (uint8_t)(u32BitLenHi >> 8u);
u8FillBuffer[57u] = (uint8_t)(u32BitLenHi >> 16u);
u8FillBuffer[56u] = (uint8_t)(u32BitLenHi >> 24u);
HASH_WriteData(u8FillBuffer);
}
/* check if first group */
if (0u == u8FirstGroup)
{
u8FirstGroup = 1u;
/* Set first group. */
bM4_HASH_CR_FST_GRP = 1u;
}
else
{
/* Set continuous group. */
bM4_HASH_CR_FST_GRP = 0u;
}
/* Start hash calculating. */
bM4_HASH_CR_START = 1u;
u32TimeCount = 0u;
enRet = ErrorTimeout;
while (u32TimeCount < u32HashTimeout)
{
if (bM4_HASH_CR_START == 0u)
{
enRet = Ok;
break;
}
u32TimeCount++;
}
if ((ErrorTimeout == enRet) || (u8HashEnd != 0u))
{
break;
}
}
if (Ok == enRet)
{
/* HASH calculated done */
HASH_GetMsgDigest(pu8MsgDigest);
}
/* Stop hash calculating. */
bM4_HASH_CR_START = 0u;
}
return enRet;
}
/*******************************************************************************
* Function implementation - local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Writes the input buffer in data register.
**
** \param [in] pu8SrcData Pointer to source data buffer.
**
** \retval None
**
******************************************************************************/
static void HASH_WriteData(const uint8_t *pu8SrcData)
{
uint8_t i;
uint8_t j;
uint32_t u32Temp;
__IO uint32_t *io32HashDr = &(M4_HASH->DR15);
for (i = 0u; i < 16u; i++)
{
j = i * 4u + 3u;
u32Temp = (uint32_t)pu8SrcData[j];
u32Temp |= ((uint32_t)pu8SrcData[j-1u]) << 8u;
u32Temp |= ((uint32_t)pu8SrcData[j-2u]) << 16u;
u32Temp |= ((uint32_t)pu8SrcData[j-3u]) << 24u;
*io32HashDr = u32Temp;
io32HashDr++;
}
}
/**
*******************************************************************************
** \brief Provides the message digest result.
**
** \param [out] pu8MsgDigest Pointer to the message digest.
**
** \retval None
**
******************************************************************************/
static void HASH_GetMsgDigest(uint8_t *pu8MsgDigest)
{
uint8_t i;
uint8_t j;
uint32_t u32Temp;
__IO uint32_t *io32HashHr = &(M4_HASH->HR7);
for (i = 0u; i < 8u; i++)
{
j = i * 4u + 3u;
u32Temp = *io32HashHr;
pu8MsgDigest[j] = (uint8_t)u32Temp;
pu8MsgDigest[j-1u] = (uint8_t)(u32Temp >> 8u);
pu8MsgDigest[j-2u] = (uint8_t)(u32Temp >> 16u);
pu8MsgDigest[j-3u] = (uint8_t)(u32Temp >> 24u);
io32HashHr++;
}
}
//@} // HashGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,433 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_i2s.c
**
** A detailed description is available at
** @link I2sGroup Inter-IC Sound Bus description @endlink
**
** - 2018-10-28 CDT First version for Device Driver Library of I2S.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_i2s.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup I2sGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter valid check for I2S register pointer */
#define IS_VALID_I2S_REG(x) \
( (M4_I2S1 == (x)) || \
(M4_I2S2 == (x)) || \
(M4_I2S3 == (x)) || \
(M4_I2S4 == (x)))
/*!< Parameter valid check for I2S function */
#define IS_VALID_I2S_FUNCTION(x) \
( (TxEn == (x)) || \
(TxIntEn == (x)) || \
(RxEn == (x)) || \
(RxIntEn == (x)) || \
(ErrIntEn == (x)))
/*!< Parameter valid check for I2S status bits */
#define IS_VALID_I2S_STATUS(x) \
( (TxBufAlarmFlag == (x)) || \
(RxBufAlarmFlag == (x)) || \
(TxBufEmptFlag == (x)) || \
(TxBufFullFlag == (x)) || \
(RxBufEmptFlag == (x)) || \
(RxBufFullFlag == (x)))
/*!< Parameter valid check for I2S error flag */
#define IS_VALID_I2S_ERR_FLAG(x) \
( (ClrTxErrFlag == (x)) || \
(ClrRxErrFlag == (x)))
/*!< Parameter valid check for I2S mode */
#define IS_VALID_I2S_MODE(x) \
( (I2sMaster == (x)) || \
(I2sSlave == (x)))
/*!< Parameter valid check for I2S full duplex mode */
#define IS_VALID_I2S_DUPLEX_MODE(x) \
( (I2s_HalfDuplex == (x)) || \
(I2s_FullDuplex == (x)))
/*!< Parameter valid check for I2S standard */
#define IS_VALID_I2S_STANDARD(x) \
( (Std_Philips == (x)) || \
(Std_MSBJust == (x)) || \
(Std_LSBJust == (x)) || \
(Std_PCM == (x)))
/*!< Parameter valid check for I2S data length */
#define IS_VALID_I2S_DATA_LEN(x) \
( (I2s_DataLen_16Bit == (x)) || \
(I2s_DataLen_24Bit == (x)) || \
(I2s_DataLen_32Bit == (x)))
/*!< Parameter valid check for I2S channel data length */
#define IS_VALID_I2S_CHANNEL_LEN(x) \
( (I2s_ChLen_16Bit == (x)) || \
(I2s_ChLen_32Bit == (x)))
/*!< Parameter valid check for I2S MCK output config */
#define IS_VALID_I2S_MCKOUT(x) \
( (Disable == (x)) || \
(Enable == (x)))
/*!< Parameter valid check for I2S EXCK config */
#define IS_VALID_I2S_EXCK(x) \
( (Disable == (x)) || \
(Enable == (x)))
/*!< Parameter valid check for I2S audio frequecy */
#define IS_I2S_AUDIO_FREQ(FREQ) \
( (((FREQ) >= I2S_AudioFreq_8k) && ((FREQ) <= I2S_AudioFreq_192k)) || \
((FREQ) == I2S_AudioFreq_Default))
/*! I2S registers reset value */
#define I2S_REG_CTRL_RESET_VALUE (0x00002200ul)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief I2S function command
**
** \param [in] pstcI2sReg Pointer to I2S register
** \param [in] enFunc I2S function
** \arg Refer @ref en_i2s_func_t
** \param [in] enNewState New status
** \arg Refer @ref en_functional_state_t
**
** \retval None
**
******************************************************************************/
void I2S_FuncCmd(M4_I2S_TypeDef* pstcI2sReg, en_i2s_func_t enFunc,
en_functional_state_t enNewState)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
DDL_ASSERT(IS_VALID_I2S_FUNCTION(enFunc));
if(Enable == enNewState)
{
if(0ul == (pstcI2sReg->CTRL & (1ul << enFunc)))
{
pstcI2sReg->CTRL |= (1ul << enFunc);
}
}
else
{
if(0ul != (pstcI2sReg->CTRL & (1ul << enFunc)))
{
pstcI2sReg->CTRL &= ~(1ul << (uint8_t)enFunc);
}
}
}
/**
*******************************************************************************
** \brief Get I2S status bit
**
** \param [in] pstcI2sReg Pointer to I2S register
** \param [in] enStd I2S status bit
** \arg Refer @ref en_i2s_std_t
**
** \retval Set flag is set
** \retval Reset flag is reset
**
******************************************************************************/
en_flag_status_t I2S_GetStatus(M4_I2S_TypeDef* pstcI2sReg, en_i2s_std_t enStd)
{
en_flag_status_t enRet = Reset;
/* Check parameters */
DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
DDL_ASSERT(IS_VALID_I2S_STATUS(enStd));
if (0ul != ((uint32_t)(pstcI2sReg->SR & (1ul << (uint8_t)enStd))))
{
enRet = Set;
}
return enRet;
}
/**
*******************************************************************************
** \brief Clear I2S error flag
**
** \param [in] pstcI2sReg Pointer to I2S register
** \param [in] enErrFlag I2S Error flag
** \arg Refer @ref en_i2s_err_flag_t
**
** \retval None
**
******************************************************************************/
void I2S_ClrErrFlag(M4_I2S_TypeDef* pstcI2sReg, en_i2s_err_flag_t enErrFlag)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
DDL_ASSERT(IS_VALID_I2S_ERR_FLAG(enErrFlag));
pstcI2sReg->ER |= (1ul << (uint8_t)enErrFlag);
}
/**
*******************************************************************************
** \brief Get I2S error flag
**
** \param [in] pstcI2sReg Pointer to I2S register
** \param [in] enErrFlag I2S Error flag
** \arg Refer @ref en_i2s_err_flag_t
**
** \retval Set flag is set
** \retval Reset flag is reset
**
******************************************************************************/
en_flag_status_t I2S_GetErrFlag(M4_I2S_TypeDef* pstcI2sReg,
en_i2s_err_flag_t enErrFlag)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
DDL_ASSERT(IS_VALID_I2S_ERR_FLAG(enErrFlag));
return (en_flag_status_t)((uint32_t)(pstcI2sReg->ER | (1ul << (uint8_t)enErrFlag)));
}
/**
*******************************************************************************
** \brief Write data to I2s data send register
**
** \param [in] pstcI2sReg Pointer to I2S register
** \param [in] u32Data Data to be send
**
** \retval None
**
******************************************************************************/
void I2S_SendData(M4_I2S_TypeDef* pstcI2sReg, uint32_t u32Data)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
pstcI2sReg->TXBUF = u32Data;
}
/**
*******************************************************************************
** \brief Read data from I2s data receive register
**
** \param [in] pstcI2sReg Pointer to I2S register
**
** \retval uint32_t The data read out
**
******************************************************************************/
uint32_t I2S_RevData(const M4_I2S_TypeDef* pstcI2sReg)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
return pstcI2sReg->RXBUF;
}
/**
*******************************************************************************
** \brief Initialize I2S module
**
** \param [in] pstcI2sReg Pointer to I2S register
** \arg M4_I2S1 I2s channel 1
** \arg M4_I2S2 I2s channel 2
** \arg M4_I2S3 I2s channel 3
** \arg M4_I2S4 I2s channel 4
** \param [in] pstcI2sCfg Pointer to I2S configuration structure
**
** \retval Ok Initialize successfully done
**
******************************************************************************/
en_result_t I2s_Init(M4_I2S_TypeDef* pstcI2sReg, const stc_i2s_config_t* pstcI2sCfg)
{
uint32_t i2sclk = 0ul, tmp=0ul;
uint8_t u8ChanelDataBit,u8ChanMul;
uint16_t i2sdiv, i2sodd;
stc_i2s_cfgr_field_t stcCFGR_Tmp = {0};
stc_i2s_ctrl_field_t stcCTRL_Tmp = {0};
en_result_t enRes = Ok;
uint32_t u32AdrTmp = 0ul;
if((NULL == pstcI2sReg)||(NULL == pstcI2sCfg))
{
enRes = ErrorInvalidParameter;
}
else
{
/* Check parameters */
DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
DDL_ASSERT(IS_VALID_I2S_MODE(pstcI2sCfg->enMode));
DDL_ASSERT(IS_VALID_I2S_DUPLEX_MODE(pstcI2sCfg->enFullDuplexMode));
DDL_ASSERT(IS_VALID_I2S_STANDARD(pstcI2sCfg->enStandrad));
DDL_ASSERT(IS_VALID_I2S_DATA_LEN(pstcI2sCfg->enDataBits));
DDL_ASSERT(IS_VALID_I2S_CHANNEL_LEN(pstcI2sCfg->enChanelLen));
DDL_ASSERT(IS_VALID_I2S_MCKOUT(pstcI2sCfg->enMcoOutEn));
DDL_ASSERT(IS_VALID_I2S_EXCK(pstcI2sCfg->enExckEn));
DDL_ASSERT(IS_I2S_AUDIO_FREQ(pstcI2sCfg->u32AudioFreq));
/* Set config register to default value*/
pstcI2sReg->CTRL = I2S_REG_CTRL_RESET_VALUE;
/* Clear status register*/
pstcI2sReg->ER_f.TXERR = 1ul;
pstcI2sReg->ER_f.RXERR = 1ul;
//*(uint32_t*)&stcCTRL_Tmp = pstcI2sReg->CTRL;
u32AdrTmp = (uint32_t)&stcCTRL_Tmp;
*(uint32_t*)u32AdrTmp = pstcI2sReg->CTRL;
/* ---- config I2s clock source---- */
if(Enable == pstcI2sCfg->enExckEn)
{
/* Set external clock as I2S clock source */
stcCTRL_Tmp.CLKSEL = 1ul;
stcCTRL_Tmp.I2SPLLSEL = 0ul;
/* Set the I2S clock to the external clock value */
i2sclk = I2S_EXTERNAL_CLOCK_VAL;
}
else
{
/* Set internal clock as I2S clock source */
stcCTRL_Tmp.CLKSEL = 0ul;
stcCTRL_Tmp.I2SPLLSEL = 1ul;
/* Get i2s clock internal frequency */
i2sclk = pstcI2sCfg->u32I2sInterClkFreq;
}
/* config audio sampple rate */
if(I2s_ChLen_16Bit == pstcI2sCfg->enChanelLen)
{
u8ChanelDataBit = 16u;
u8ChanMul = 8u;
}
else
{
u8ChanelDataBit = 32u;
u8ChanMul = 4u;
}
/*config I2S clock*/
if(true == pstcI2sCfg->enMcoOutEn)
{
/* MCLK output is enabled */
tmp = i2sclk/(pstcI2sCfg->u32AudioFreq * u8ChanelDataBit * 2ul * u8ChanMul);
}
else
{
/* MCLK output is disabled */
tmp = i2sclk/(pstcI2sCfg->u32AudioFreq * u8ChanelDataBit * 2ul);
}
i2sodd = (uint16_t)(tmp & 0x0001ul);
i2sdiv = (uint16_t)((tmp - (uint32_t)i2sodd) / 2ul);
/* Test if the divider is 1 or 0 or greater than 0xFF */
if ((i2sdiv < 2u) || (i2sdiv > 0xFFu))
{
/* Set the default values */
i2sdiv = 2u;
i2sodd = 0u;
}
/* Write I2SPR register */
pstcI2sReg->PR_f.I2SDIV = (uint8_t)i2sdiv;
/* Config and write I2S_CFGR */
stcCFGR_Tmp.CHLEN = pstcI2sCfg->enChanelLen;
stcCFGR_Tmp.DATLEN = pstcI2sCfg->enDataBits;
stcCFGR_Tmp.I2SSTD = pstcI2sCfg->enStandrad;
stcCFGR_Tmp.PCMSYNC = PCM_SYNC_FRAME;
pstcI2sReg->CFGR_f = stcCFGR_Tmp;
/* Config CTRL register */
stcCTRL_Tmp.WMS = pstcI2sCfg->enMode;
stcCTRL_Tmp.DUPLEX = pstcI2sCfg->enFullDuplexMode;
if(I2sMaster == pstcI2sCfg->enMode)
{
stcCTRL_Tmp.CKOE = 1u;
stcCTRL_Tmp.LRCKOE = 1u;
}
stcCTRL_Tmp.SDOE = 1u;
stcCTRL_Tmp.MCKOE = pstcI2sCfg->enMcoOutEn;
stcCTRL_Tmp.ODD = (uint8_t)i2sodd;
stcCTRL_Tmp.RXBIRQWL = RXBUF_IRQ_WL;
stcCTRL_Tmp.TXBIRQWL = TXBUF_IRQ_WL;
//pstcI2sReg->CTRL = *(uint32_t*)&stcCTRL_Tmp;
u32AdrTmp = (uint32_t)&stcCTRL_Tmp;
pstcI2sReg->CTRL = *(uint32_t*)u32AdrTmp;
}
return enRes;
}
/**
*******************************************************************************
** \brief De-Initialize I2S module
**
** \param [in] pstcI2sReg Pointer to I2S register
** \arg M4_I2S1 I2s channel 1
** \arg M4_I2S2 I2s channel 2
** \arg M4_I2S3 I2s channel 3
** \arg M4_I2S4 I2s channel 4
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t I2s_DeInit(M4_I2S_TypeDef* pstcI2sReg)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_I2S_REG(pstcI2sReg));
/* Set config register to default value*/
pstcI2sReg->CTRL = I2S_REG_CTRL_RESET_VALUE;
/* Clear status register*/
pstcI2sReg->ER_f.TXERR = 1u;
pstcI2sReg->ER_f.RXERR = 1u;
return Ok;
}
//@} // I2sGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,79 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_icg.c
**
** A detailed description is available at
** @link IcgGroup Initialize Configure description @endlink
**
** - 2018-10-15 CDT First version for Device Driver Library of ICG.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_icg.h"
/**
*******************************************************************************
** \addtogroup IcgGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
const uint32_t u32ICG[] __attribute__((section(".icg_sec"))) =
#elif defined (__CC_ARM)
const uint32_t u32ICG[] __attribute__((at(0x400))) =
#elif defined (__ICCARM__)
__root const uint32_t u32ICG[] @ 0x400 =
#else
#error "unsupported compiler!!"
#endif
{
/* ICG 0~ 3 */
ICG0_REGISTER_CONSTANT,
ICG1_REGISTER_CONSTANT,
ICG2_REGISTER_CONSTANT,
ICG3_REGISTER_CONSTANT,
/* ICG 4~ 7 */
ICG4_REGISTER_CONSTANT,
ICG5_REGISTER_CONSTANT,
ICG6_REGISTER_CONSTANT,
ICG7_REGISTER_CONSTANT,
};
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
//@} // IcgGroup
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,203 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_keyscan.c
**
** A detailed description is available at
** @link KeyscanGroup Keyscan module description @endlink
**
** - 2018-10-17 CDT First version for Device Driver Library of keyscan.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_keyscan.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup KeyscanGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*! Parameter validity check for Hiz cycle */
#define IS_VALID_HIZ_CLCYE(x) \
( ((x) == Hiz4) || \
((x) == Hiz8) || \
((x) == Hiz16) || \
((x) == Hiz32) || \
((x) == Hiz64) || \
((x) == Hiz256) || \
((x) == Hiz512) || \
((x) == Hiz1K))
/*! Parameter validity check for Low cycle */
#define IS_VALID_LOW_CLCYE(x) \
( ((x) == Low8) || \
((x) == Low16) || \
((x) == Low32) || \
((x) == Low64) || \
((x) == Low128) || \
((x) == Low256) || \
((x) == Low512) || \
((x) == Low1K) || \
((x) == Low2K) || \
((x) == Low4K) || \
((x) == Low8K) || \
((x) == Low16K) || \
((x) == Low32K) || \
((x) == Low64K) || \
((x) == Low128K) || \
((x) == Low256K) || \
((x) == Low512K) || \
((x) == Low1M) || \
((x) == Low2M) || \
((x) == Low4M) || \
((x) == Low8M) || \
((x) == Low16M))
/*! Parameter validity check for scan clock */
#define IS_VALID_SCAN_CLK(x) \
( ((x) == KeyscanHclk) || \
((x) == KeyscanLrc) || \
((x) == KeyscanXtal32))
/*! Parameter validity check for keyout selection */
#define IS_VALID_KEY_OUT(x) \
( ((x) == Keyout0To1) || \
((x) == Keyout0To2) || \
((x) == Keyout0To3) || \
((x) == Keyout0To4) || \
((x) == Keyout0To5) || \
((x) == Keyout0To6) || \
((x) == Keyout0To7))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief KEYSCAN initialization
**
** \param [in] pstcKeyscanConfig KEYSCAN configure structure
**
** \retval Ok KEYSCAN initialized
** ErrorInvalidMode Uninitialized, cannot configure it properly
**
******************************************************************************/
en_result_t KEYSCAN_Init(const stc_keyscan_config_t *pstcKeyscanConfig)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_HIZ_CLCYE(pstcKeyscanConfig->enHizCycle));
DDL_ASSERT(IS_VALID_LOW_CLCYE(pstcKeyscanConfig->enLowCycle));
DDL_ASSERT(IS_VALID_SCAN_CLK(pstcKeyscanConfig->enKeyscanClk));
DDL_ASSERT(IS_VALID_KEY_OUT(pstcKeyscanConfig->enKeyoutSel));
/* cannot configure keyscan control register when running */
if (Set == M4_KEYSCAN->SER_f.SEN)
{
enRet = ErrorInvalidMode;
}
else
{
M4_KEYSCAN->SCR_f.T_HIZ = pstcKeyscanConfig->enHizCycle;
M4_KEYSCAN->SCR_f.T_LLEVEL = pstcKeyscanConfig->enLowCycle;
M4_KEYSCAN->SCR_f.CKSEL = pstcKeyscanConfig->enKeyscanClk;
M4_KEYSCAN->SCR_f.KEYOUTSEL = pstcKeyscanConfig->enKeyoutSel;
M4_KEYSCAN->SCR_f.KEYINSEL = pstcKeyscanConfig->u16KeyinSel;
}
return enRet;
}
/**
*******************************************************************************
** \brief KEYSCAN de-initialization
**
** \param None
**
** \retval Ok KEYSCAN de-initialized
**
******************************************************************************/
en_result_t KEYSCAN_DeInit(void)
{
M4_KEYSCAN->SER = 0ul;
M4_KEYSCAN->SCR = 0ul;
return Ok;
}
/**
*******************************************************************************
** \brief Start keyscan function
**
** \param None
**
** \retval Ok Keyscan function started
**
******************************************************************************/
en_result_t KEYSCAN_Start(void)
{
M4_KEYSCAN->SER_f.SEN = Set;
return Ok;
}
/**
*******************************************************************************
** \brief Stop keyscan function
**
** \param None
**
** \retval Ok Keyscan function stopped
**
******************************************************************************/
en_result_t KEYSCAN_Stop(void)
{
M4_KEYSCAN->SER_f.SEN = Reset;
return Ok;
}
/**
*******************************************************************************
** \brief Get Key column index
**
** \param None
**
** \retval uint8_t Index of KEYOUT
**
******************************************************************************/
uint8_t KEYSCAN_GetColIdx(void)
{
return (uint8_t)(M4_KEYSCAN->SSR_f.INDEX);
}
//@} // KeyscanGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,382 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_ots.c
**
** A detailed description is available at
** @link OtsGroup Ots description @endlink
**
** - 2018-10-26 CDT First version for Device Driver Library of Ots.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_ots.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup OtsGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*! Parameter validity check for OTS auto off configuration value. */
#define IS_OTS_AUTO_OFF(EN) \
( ((EN) == OtsAutoOff_Disable) || \
((EN) == OtsAutoOff_Enable))
/*! Parameter validity check for OTS interrupt enable/disable. */
#define IS_OTS_IE(IE) \
( ((IE) == OtsInt_Disable) || \
((IE) == OtsInt_Enable))
/*! Parameter validity check for OTS clock selection configuration value. */
#define IS_OTS_CLK_SEL(CLK) \
( ((CLK) == OtsClkSel_Xtal) || \
((CLK) == OtsClkSel_Hrc))
/*! Parameter validity check for OTS trigger source event . */
#define IS_OTS_TRIG_SRC_EVENT(x) \
( (((x) >= EVT_PORT_EIRQ0) && ((x) <= EVT_PORT_EIRQ15)) || \
(((x) >= EVT_DMA1_TC0) && ((x) <= EVT_DMA2_BTC3)) || \
(((x) >= EVT_EFM_OPTEND) && ((x) <= EVT_USBFS_SOF)) || \
(((x) >= EVT_DCU1) && ((x) <= EVT_DCU4)) || \
(((x) >= EVT_TMR01_GCMA) && ((x) <= EVT_TMR02_GCMB)) || \
(((x) >= EVT_RTC_ALM) && ((x) <= EVT_RTC_PRD)) || \
(((x) >= EVT_TMR61_GCMA) && ((x) <= EVT_TMR61_GUDF)) || \
(((x) >= EVT_TMR61_SCMA) && ((x) <= EVT_TMR61_SCMB)) || \
(((x) >= EVT_TMR62_GCMA) && ((x) <= EVT_TMR62_GUDF)) || \
(((x) >= EVT_TMR62_SCMA) && ((x) <= EVT_TMR62_SCMB)) || \
(((x) >= EVT_TMR63_GCMA) && ((x) <= EVT_TMR63_GUDF)) || \
(((x) >= EVT_TMR63_SCMA) && ((x) <= EVT_TMR63_SCMB)) || \
(((x) >= EVT_TMRA1_OVF) && ((x) <= EVT_TMRA5_CMP)) || \
(((x) >= EVT_TMRA6_OVF) && ((x) <= EVT_TMRA6_CMP)) || \
(((x) >= EVT_USART1_EI) && ((x) <= EVT_USART4_RTO)) || \
(((x) >= EVT_SPI1_SPRI) && ((x) <= EVT_AOS_STRG)) || \
(((x) >= EVT_TMR41_SCMUH) && ((x) <= EVT_TMR42_SCMWL)) || \
(((x) >= EVT_TMR43_SCMUH) && ((x) <= EVT_TMR43_SCMWL)) || \
(((x) >= EVT_EVENT_PORT1) && ((x) <= EVT_EVENT_PORT4)) || \
(((x) >= EVT_I2S1_TXIRQOUT) && ((x) <= EVT_I2S1_RXIRQOUT)) || \
(((x) >= EVT_I2S2_TXIRQOUT) && ((x) <= EVT_I2S2_RXIRQOUT)) || \
(((x) >= EVT_I2S3_TXIRQOUT) && ((x) <= EVT_I2S3_RXIRQOUT)) || \
(((x) >= EVT_I2S4_TXIRQOUT) && ((x) <= EVT_I2S4_RXIRQOUT)) || \
(((x) >= EVT_ACMP1) && ((x) <= EVT_ACMP3)) || \
(((x) >= EVT_I2C1_RXI) && ((x) <= EVT_I2C3_EEI)) || \
(((x) >= EVT_PVD_PVD1) && ((x) <= EVT_OTS)) || \
((x) == EVT_WDT_REFUDF) || \
(((x) >= EVT_ADC1_EOCA) && ((x) <= EVT_TRNG_END)) || \
(((x) >= EVT_SDIOC1_DMAR) && ((x) <= EVT_SDIOC1_DMAW)) || \
(((x) >= EVT_SDIOC2_DMAR) && ((x) <= EVT_SDIOC2_DMAW)) || \
((x) == EVT_MAX))
/*! Parameter validity check for OTS common trigger. */
#define IS_OTS_COM_TRIGGER(x) \
( ((x) == OtsComTrigger_1) || \
((x) == OtsComTrigger_2) || \
((x) == OtsComTrigger_1_2))
#define EXPERIMENT_COUNT ((uint8_t)10)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
static float32_t m_f32SlopeK = 0.0f;
static float32_t m_f32OffsetM = 0.0f;
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initializes the OTS.
**
** \param [in] pstcInit See @ref stc_ots_init_t for details.
**
** \retval Ok No error occurred.
** \retval ErrorInvalidParameter Parameter error.
**
******************************************************************************/
en_result_t OTS_Init(const stc_ots_init_t *pstcInit)
{
en_result_t enRet = ErrorInvalidParameter;
if (NULL != pstcInit)
{
DDL_ASSERT(IS_OTS_AUTO_OFF(pstcInit->enAutoOff));
DDL_ASSERT(IS_OTS_CLK_SEL(pstcInit->enClkSel));
/* Stop ots sampling. */
bM4_OTS_CTL_OTSST = 0u;
/* Disable OTS interrupt default. */
bM4_OTS_CTL_OTSIE = OtsInt_Disable;
bM4_OTS_CTL_TSSTP = pstcInit->enAutoOff;
bM4_OTS_CTL_OTSCK = pstcInit->enClkSel;
m_f32SlopeK = pstcInit->f32SlopeK;
m_f32OffsetM = pstcInit->f32OffsetM;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Deinitializes the TRNG.
**
** \param None.
**
** \retval None.
**
******************************************************************************/
void OTS_DeInit(void)
{
/* Stop ots sampling. */
bM4_OTS_CTL_OTSST = 0u;
/* Set the value of all registers to the reset value. */
M4_OTS->CTL = 0u;
M4_OTS->DR1 = 0u;
M4_OTS->DR2 = 0u;
M4_OTS->ECR = 0u;
}
/**
*******************************************************************************
** \brief Get temperature via normal mode.
**
** \param [out] pf32Temp The address to store the temperature value.
**
** \param [in] u32Timeout Timeout value.
**
** \retval Ok No error occurred.
** \retval ErrorTimeout OTS works timeout.
** \retval ErrorInvalidParameter Parameter error.
**
******************************************************************************/
en_result_t OTS_Polling(float32_t *pf32Temp, uint32_t u32Timeout)
{
en_result_t enRet = ErrorInvalidParameter;
if (pf32Temp != NULL)
{
enRet = ErrorTimeout;
OTS_Start();
do
{
if (bM4_OTS_CTL_OTSST == 0ul)
{
*pf32Temp = OTS_CalculateTemp();
enRet = Ok;
break;
}
} while (u32Timeout-- != 0ul);
OTS_Stop();
}
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable OTS interrupt.
**
** \param [in] enState Enable or disable OTS interrupt.
**
** \retval None.
**
******************************************************************************/
void OTS_IntCmd(en_functional_state_t enState)
{
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
bM4_OTS_CTL_OTSIE = (uint32_t)enState;
}
/**
*******************************************************************************
** \brief Set OTS AOS trigger source.
**
** \param [in] enEvent See @ref en_event_src_t for details.
**
** \retval None.
**
******************************************************************************/
void OTS_SetTriggerSrc(en_event_src_t enEvent)
{
uint32_t u32OtrTrg = M4_AOS->OTS_TRG;
DDL_ASSERT(IS_OTS_TRIG_SRC_EVENT(enEvent) && (EVT_OTS != enEvent));
u32OtrTrg &= ~0x1FFul;
u32OtrTrg |= enEvent;
M4_AOS->OTS_TRG = u32OtrTrg;
}
/**
*******************************************************************************
** \brief Enable or disable OTS common trigger.
**
** \param [in] enComTrigger OTS common trigger selection. See @ref en_ots_com_trigger_t for details.
**
** \param [in] enState Enable or disable the specified common trigger.
**
** \retval None.
**
******************************************************************************/
void OTS_ComTriggerCmd(en_ots_com_trigger_t enComTrigger, en_functional_state_t enState)
{
uint32_t u32ComTrig = enComTrigger;
DDL_ASSERT(IS_OTS_COM_TRIGGER(enComTrigger));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
u32ComTrig <<= 30u;
if (enState == Enable)
{
M4_AOS->OTS_TRG |= u32ComTrig;
}
else
{
M4_AOS->OTS_TRG &= ~u32ComTrig;
}
}
/**
*******************************************************************************
** \brief OTS scaling experiment. If you want to get a more accurate temperature value,
** you need to do a calibration experiment.
**
** \param [out] pu16Dr1 Address to store OTS data register 1.
**
** \param [out] pu16Dr2 Address to store OTS data register 2.
**
** \param [out] pu16Ecr Address to store OTS error compensation register.
**
** \param [out] pf32A Address to store parameter A(for calibration experiments).
**
** \param [in] u32Timeout Timeout value.
**
** \retval Ok No error occurred.
** \retval ErrorTimeout OTS works timeout.
** \retval ErrorInvalidParameter Parameter error.
******************************************************************************/
en_result_t OTS_ScalingExperiment(uint16_t *pu16Dr1, uint16_t *pu16Dr2, \
uint16_t *pu16Ecr, float32_t *pf32A, \
uint32_t u32Timeout)
{
float32_t f32Dr1;
float32_t f32Dr2;
float32_t f32Ecr;
en_result_t enRet = ErrorInvalidParameter;
if ((NULL != pu16Dr1) && (NULL != pu16Dr2) && \
(NULL != pu16Ecr) && (NULL != pf32A))
{
enRet = ErrorTimeout;
OTS_Start();
do
{
if (bM4_OTS_CTL_OTSST == 0ul)
{
enRet = Ok;
break;
}
} while (u32Timeout-- != 0ul);
OTS_Stop();
if (enRet == Ok)
{
*pu16Dr1 = M4_OTS->DR1;
*pu16Dr2 = M4_OTS->DR2;
f32Dr1 = (float32_t)(*pu16Dr1);
f32Dr2 = (float32_t)(*pu16Dr2);
if (bM4_OTS_CTL_OTSCK == OtsClkSel_Hrc)
{
*pu16Ecr = M4_OTS->ECR;
f32Ecr = (float32_t)(*pu16Ecr);
}
else
{
*pu16Ecr = 1U;
f32Ecr = 1.0f;
}
if ((f32Dr1 != 0.f) && (f32Dr2 != 0.f) && (f32Ecr != 0.f))
{
*pf32A = ((1.0f / f32Dr1) - (1.0f / f32Dr2)) * f32Ecr;
}
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Calculate the value of temperature.
**
** \retval A float32_t type value of temperature value.
******************************************************************************/
float OTS_CalculateTemp(void)
{
float32_t f32Ret = 0.0f;
uint16_t u16Dr1 = M4_OTS->DR1;
uint16_t u16Dr2 = M4_OTS->DR2;
uint16_t u16Ecr = M4_OTS->ECR;
float32_t f32Dr1 = (float32_t)u16Dr1;
float32_t f32Dr2 = (float32_t)u16Dr2;
float32_t f32Ecr = (float32_t)u16Ecr;
if (bM4_OTS_CTL_OTSCK == OtsClkSel_Xtal)
{
f32Ecr = 1.0f;
}
if ((f32Dr1 != 0.f) && (f32Dr2 != 0.f) && (f32Ecr != 0.f))
{
f32Ret = m_f32SlopeK * ((1.0f / f32Dr1) - (1.0f / f32Dr2)) * f32Ecr + m_f32OffsetM;
}
return f32Ret;
}
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
//@} // OtsGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,752 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_qspi.c
**
** A detailed description is available at
** @link QspiGroup Queued SPI description @endlink
**
** - 2018-11-20 CDT First version for Device Driver Library of Qspi.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_qspi.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup QspiGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter valid check for clock division */
#define IS_VALID_CLK_DIV(x) \
( ((x) == QspiHclkDiv2) || \
(((x) >= QspiHclkDiv3) && ((x) <= QspiHclkDiv64)))
/*!< Parameter valid check for spi mode */
#define IS_VALID_SPI_MODE(x) \
( (QspiSpiMode0 == (x)) || \
(QspiSpiMode3 == (x)))
/*!< Parameter valid check for bus communication mode */
#define IS_VALID_BUS_COMM_MODE(x) \
( (QspiBusModeRomAccess == (x)) || \
(QspiBusModeDirectAccess == (x)))
/*!< Parameter valid check for prefetch stop location */
#define IS_VALID_PREFETCH_STOP_LOCATION(x) \
( (QspiPrefetchStopComplete == (x)) || \
(QspiPrefetchStopImmediately == (x)))
/*!< Parameter valid check for receive data protocol */
#define IS_VALID_RECE_DATA_PROTOCOL(x) \
( (QspiProtocolExtendSpi == (x)) || \
(QspiProtocolTwoWiresSpi == (x)) || \
(QspiProtocolFourWiresSpi == (x)))
/*!< Parameter valid check for transmit address protocol */
#define IS_VALID_TRANS_ADDR_PROTOCOL(x) \
( (QspiProtocolExtendSpi == (x)) || \
(QspiProtocolTwoWiresSpi == (x)) || \
(QspiProtocolFourWiresSpi == (x)))
/*!< Parameter valid check for transmit instruction protocol */
#define IS_VALID_TRANS_INSTRUCT_PROTOCOL(x) \
( (QspiProtocolExtendSpi == (x)) || \
(QspiProtocolTwoWiresSpi == (x)) || \
(QspiProtocolFourWiresSpi == (x)))
/*!< Parameter valid check for serial interface read mode */
#define IS_VALID_INTERFACE_READ_MODE(x) \
( (QspiReadModeStandard == (x)) || \
(QspiReadModeFast == (x)) || \
(QspiReadModeTwoWiresOutput == (x)) || \
(QspiReadModeTwoWiresIO == (x)) || \
(QspiReadModeFourWiresOutput == (x)) || \
(QspiReadModeFourWiresIO == (x)) || \
(QspiReadModeCustomStandard == (x)) || \
(QspiReadModeCustomFast == (x)))
/*!< Parameter valid check for QSSN valid extend delay time */
#define IS_VALID_QSSN_VALID_EXTEND_TIME(x) \
( (QspiQssnValidExtendNot == (x)) || \
(QspiQssnValidExtendSck32 == (x)) || \
(QspiQssnValidExtendSck128 == (x)) || \
(QspiQssnValidExtendSckEver == (x)))
/*!< Parameter valid check for QSSN minimum interval time */
#define IS_VALID_QSSN_INTERVAL_TIME(x) \
( (QspiQssnIntervalQsck1 == (x)) || \
(QspiQssnIntervalQsck2 == (x)) || \
(QspiQssnIntervalQsck3 == (x)) || \
(QspiQssnIntervalQsck4 == (x)) || \
(QspiQssnIntervalQsck5 == (x)) || \
(QspiQssnIntervalQsck6 == (x)) || \
(QspiQssnIntervalQsck7 == (x)) || \
(QspiQssnIntervalQsck8 == (x)) || \
(QspiQssnIntervalQsck9 == (x)) || \
(QspiQssnIntervalQsck10 == (x)) || \
(QspiQssnIntervalQsck11 == (x)) || \
(QspiQssnIntervalQsck12 == (x)) || \
(QspiQssnIntervalQsck13 == (x)) || \
(QspiQssnIntervalQsck14 == (x)) || \
(QspiQssnIntervalQsck15 == (x)) || \
(QspiQssnIntervalQsck16 <= (x)))
/*!< Parameter valid check for QSCK duty correction */
#define IS_VALID_QSCK_DUTY_CORR(x) \
( (QspiQsckDutyCorrNot == (x)) || \
(QspiQsckDutyCorrHalfHclk == (x)))
/*!< Parameter valid check for virtual cycles */
#define IS_VALID_VIRTUAL_CYCLES(x) \
( (QspiVirtualPeriodQsck3 == (x)) || \
(QspiVirtualPeriodQsck4 == (x)) || \
(QspiVirtualPeriodQsck5 == (x)) || \
(QspiVirtualPeriodQsck6 == (x)) || \
(QspiVirtualPeriodQsck7 == (x)) || \
(QspiVirtualPeriodQsck8 == (x)) || \
(QspiVirtualPeriodQsck9 == (x)) || \
(QspiVirtualPeriodQsck10 == (x)) || \
(QspiVirtualPeriodQsck11 == (x)) || \
(QspiVirtualPeriodQsck12 == (x)) || \
(QspiVirtualPeriodQsck13 == (x)) || \
(QspiVirtualPeriodQsck14 == (x)) || \
(QspiVirtualPeriodQsck15 == (x)) || \
(QspiVirtualPeriodQsck16 == (x)) || \
(QspiVirtualPeriodQsck17 == (x)) || \
(QspiVirtualPeriodQsck18 == (x)))
/*!< Parameter valid check for WP pin output level */
#define IS_VALID_WP_OUTPUT_LEVEL(x) \
( (QspiWpPinOutputLow == (x)) || \
(QspiWpPinOutputHigh == (x)))
/*!< Parameter valid check for QSSN setup delay time */
#define IS_VALID_QSSN_SETUP_DELAY(x) \
( (QspiQssnSetupDelayHalfQsck == (x)) || \
(QspiQssnSetupDelay1Dot5Qsck == (x)))
/*!< Parameter valid check for QSSN hold delay time */
#define IS_VALID_QSSN_HOLD_TIME(x) \
( (QspiQssnHoldDelayHalfQsck == (x)) || \
(QspiQssnHoldDelay1Dot5Qsck == (x)))
/*!< Parameter valid check for interface address width */
#define IS_VALID_INTERFACE_ADDR_WIDTH(x) \
( (QspiAddressByteOne == (x)) || \
(QspiAddressByteTwo == (x)) || \
(QspiAddressByteThree == (x)) || \
(QspiAddressByteFour == (x)))
/*!< Parameter valid check for extend address */
#define IS_VALID_SET_EXTEND_ADDR(x) ((x) <= 0x3Fu)
/*!< Parameter valid check for get flag type */
#define IS_VALID_GET_FLAG_TYPE(x) \
( (QspiFlagBusBusy == (x)) || \
(QspiFlagXipMode == (x)) || \
(QspiFlagRomAccessError == (x)) || \
(QspiFlagPrefetchBufferFull == (x)) || \
(QspiFlagPrefetchStop == (x)))
/*!< Parameter valid check for clear flag type */
#define IS_VALID_CLEAR_FLAG_TYPE(x) (QspiFlagRomAccessError == (x))
/*!< QSPI registers reset value */
#define QSPI_REG_CR_RESET_VALUE (0x003F0000ul)
#define QSPI_REG_CSCR_RESET_VALUE (0x0000000Ful)
#define QSPI_REG_FCR_RESET_VALUE (0x000080B3ul)
#define QSPI_REG_SR_RESET_VALUE (0x00008000ul)
#define QSPI_REG_CCMD_RESET_VALUE (0x00000000ul)
#define QSPI_REG_XCMD_RESET_VALUE (0x000000FFul)
#define QSPI_REG_EXAR_RESET_VALUE (0x00000000ul)
#define QSPI_REG_SR2_RESET_VALUE (0x00000000ul)
#define QSPI_REG_DCOM_RESET_VALUE (0x00000000ul)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief De-Initialize QSPI unit
**
** \param [in] None
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_DeInit(void)
{
en_result_t enRet = Ok;
M4_QSPI->CR = QSPI_REG_CR_RESET_VALUE;
if (1u == M4_QSPI->SR_f.RAER)
{
M4_QSPI->SR2_f.RAERCLR = 1u;
}
M4_QSPI->CSCR = QSPI_REG_CSCR_RESET_VALUE;
M4_QSPI->FCR = QSPI_REG_FCR_RESET_VALUE;
M4_QSPI->EXAR = QSPI_REG_EXAR_RESET_VALUE;
M4_QSPI->SR = QSPI_REG_SR_RESET_VALUE;
M4_QSPI->CCMD = QSPI_REG_CCMD_RESET_VALUE;
M4_QSPI->XCMD = QSPI_REG_XCMD_RESET_VALUE;
M4_QSPI->DCOM = QSPI_REG_DCOM_RESET_VALUE;
M4_QSPI->SR2 = QSPI_REG_SR2_RESET_VALUE;
return enRet;
}
/**
*******************************************************************************
** \brief Initialize QSPI unit
**
** \param [in] pstcQspiInitCfg Pointer to qspi configuration
** \arg See the struct #stc_qspi_init_t
**
** \retval Ok Process successfully done
** \retval Error Parameter error
**
******************************************************************************/
en_result_t QSPI_Init(const stc_qspi_init_t *pstcQspiInitCfg)
{
en_result_t enRet = Ok;
if (NULL == pstcQspiInitCfg)
{
enRet = Error;
}
else
{
/* Check parameters */
DDL_ASSERT(IS_VALID_CLK_DIV(pstcQspiInitCfg->enClkDiv));
DDL_ASSERT(IS_VALID_SPI_MODE(pstcQspiInitCfg->enSpiMode));
DDL_ASSERT(IS_VALID_BUS_COMM_MODE(pstcQspiInitCfg->enBusCommMode));
DDL_ASSERT(IS_VALID_PREFETCH_STOP_LOCATION(pstcQspiInitCfg->enPrefetchMode));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcQspiInitCfg->enPrefetchFuncEn));
DDL_ASSERT(IS_VALID_RECE_DATA_PROTOCOL(pstcQspiInitCfg->stcCommProtocol.enReceProtocol));
DDL_ASSERT(IS_VALID_TRANS_ADDR_PROTOCOL(pstcQspiInitCfg->stcCommProtocol.enTransAddrProtocol));
DDL_ASSERT(IS_VALID_TRANS_INSTRUCT_PROTOCOL(pstcQspiInitCfg->stcCommProtocol.enTransInstrProtocol));
DDL_ASSERT(IS_VALID_INTERFACE_READ_MODE(pstcQspiInitCfg->stcCommProtocol.enReadMode));
DDL_ASSERT(IS_VALID_QSSN_VALID_EXTEND_TIME(pstcQspiInitCfg->enQssnValidExtendTime));
DDL_ASSERT(IS_VALID_QSSN_INTERVAL_TIME(pstcQspiInitCfg->enQssnIntervalTime));
DDL_ASSERT(IS_VALID_QSCK_DUTY_CORR(pstcQspiInitCfg->enQsckDutyCorr));
DDL_ASSERT(IS_VALID_VIRTUAL_CYCLES(pstcQspiInitCfg->enVirtualPeriod));
DDL_ASSERT(IS_VALID_WP_OUTPUT_LEVEL(pstcQspiInitCfg->enWpPinLevel));
DDL_ASSERT(IS_VALID_QSSN_SETUP_DELAY(pstcQspiInitCfg->enQssnSetupDelayTime));
DDL_ASSERT(IS_VALID_QSSN_HOLD_TIME(pstcQspiInitCfg->enQssnHoldDelayTime));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcQspiInitCfg->enFourByteAddrReadEn));
DDL_ASSERT(IS_VALID_INTERFACE_ADDR_WIDTH(pstcQspiInitCfg->enAddrWidth));
/* Configure control register */
M4_QSPI->CR_f.DIV = pstcQspiInitCfg->enClkDiv;
M4_QSPI->CR_f.SPIMD3 = pstcQspiInitCfg->enSpiMode;
M4_QSPI->CR_f.PFE = pstcQspiInitCfg->enPrefetchFuncEn;
M4_QSPI->CR_f.PFSAE = pstcQspiInitCfg->enPrefetchMode;
M4_QSPI->CR_f.MDSEL = pstcQspiInitCfg->stcCommProtocol.enReadMode;
/* Custom read mode */
if ((QspiReadModeCustomFast == pstcQspiInitCfg->stcCommProtocol.enReadMode) ||
(QspiReadModeCustomStandard == pstcQspiInitCfg->stcCommProtocol.enReadMode))
{
M4_QSPI->CR_f.IPRSL = pstcQspiInitCfg->stcCommProtocol.enTransInstrProtocol;
M4_QSPI->CR_f.APRSL = pstcQspiInitCfg->stcCommProtocol.enTransAddrProtocol;
M4_QSPI->CR_f.DPRSL = pstcQspiInitCfg->stcCommProtocol.enReceProtocol;
}
else
{
M4_QSPI->CR_f.IPRSL = QspiProtocolExtendSpi;
M4_QSPI->CR_f.APRSL = QspiProtocolExtendSpi;
M4_QSPI->CR_f.DPRSL = QspiProtocolExtendSpi;
}
/* Configure chip select control register */
M4_QSPI->CSCR_f.SSNW = pstcQspiInitCfg->enQssnValidExtendTime;
M4_QSPI->CSCR_f.SSHW = pstcQspiInitCfg->enQssnIntervalTime;
/* Configure format control register */
if (((pstcQspiInitCfg->enClkDiv % 2) != 0) &&
(pstcQspiInitCfg->enQsckDutyCorr != QspiQsckDutyCorrNot))
{
M4_QSPI->FCR_f.DUTY = QspiQsckDutyCorrNot;
}
else
{
M4_QSPI->FCR_f.DUTY = pstcQspiInitCfg->enQsckDutyCorr;
}
M4_QSPI->FCR_f.DMCYCN = pstcQspiInitCfg->enVirtualPeriod;
M4_QSPI->FCR_f.WPOL = pstcQspiInitCfg->enWpPinLevel;
M4_QSPI->FCR_f.SSNLD = pstcQspiInitCfg->enQssnSetupDelayTime;
M4_QSPI->FCR_f.SSNHD = pstcQspiInitCfg->enQssnHoldDelayTime;
M4_QSPI->FCR_f.FOUR_BIC = pstcQspiInitCfg->enFourByteAddrReadEn;
M4_QSPI->FCR_f.AWSL = pstcQspiInitCfg->enAddrWidth;
M4_QSPI->CR_f.DCOME = pstcQspiInitCfg->enBusCommMode;
/* Configure ROM access instruction */
M4_QSPI->CCMD = pstcQspiInitCfg->u8RomAccessInstr;
}
return enRet;
}
/**
*******************************************************************************
** \brief Config communication protocol structure
**
** \param [in] pstcCommProtocol Pointer to qspi communication protocol configuration
** \arg See the struct #stc_qspi_comm_protocol_t
**
** \retval Ok Process successfully done
** \retval Error Parameter error
**
******************************************************************************/
en_result_t QSPI_CommProtocolConfig(const stc_qspi_comm_protocol_t *pstcCommProtocol)
{
en_result_t enRet = Ok;
if (NULL == pstcCommProtocol)
{
enRet = Error;
}
else
{
DDL_ASSERT(IS_VALID_RECE_DATA_PROTOCOL(pstcCommProtocol->enReceProtocol));
DDL_ASSERT(IS_VALID_TRANS_ADDR_PROTOCOL(pstcCommProtocol->enTransAddrProtocol));
DDL_ASSERT(IS_VALID_TRANS_INSTRUCT_PROTOCOL(pstcCommProtocol->enTransInstrProtocol));
DDL_ASSERT(IS_VALID_INTERFACE_READ_MODE(pstcCommProtocol->enReadMode));
M4_QSPI->CR_f.MDSEL = pstcCommProtocol->enReadMode;
/* Custom read mode */
if ((QspiReadModeCustomFast == pstcCommProtocol->enReadMode) ||
(QspiReadModeCustomStandard == pstcCommProtocol->enReadMode))
{
M4_QSPI->CR_f.IPRSL = pstcCommProtocol->enTransInstrProtocol;
M4_QSPI->CR_f.APRSL = pstcCommProtocol->enTransAddrProtocol;
M4_QSPI->CR_f.DPRSL = pstcCommProtocol->enReceProtocol;
}
else
{
M4_QSPI->CR_f.IPRSL = QspiProtocolExtendSpi;
M4_QSPI->CR_f.APRSL = QspiProtocolExtendSpi;
M4_QSPI->CR_f.DPRSL = QspiProtocolExtendSpi;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable prefetch function
**
** \param [in] enNewSta The function new state
** \arg Disable Disable prefetch function
** \arg Enable Enable prefetch function
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_PrefetchCmd(en_functional_state_t enNewSta)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
M4_QSPI->CR_f.PFE = enNewSta;
return enRet;
}
/**
*******************************************************************************
** \brief Set clock division
**
** \param [in] enClkDiv Clock division
** \arg QspiHclkDiv2 Clock source: HCLK/2
** \arg QspiHclkDiv3 Clock source: HCLK/3
** \arg QspiHclkDiv4 Clock source: HCLK/4
** \arg QspiHclkDiv5 Clock source: HCLK/5
** \arg QspiHclkDiv6 Clock source: HCLK/6
** \arg QspiHclkDiv7 Clock source: HCLK/7
** \arg QspiHclkDiv8 Clock source: HCLK/8
** \arg QspiHclkDiv9 Clock source: HCLK/9
** \arg QspiHclkDiv10 Clock source: HCLK/10
** \arg QspiHclkDiv11 Clock source: HCLK/11
** \arg QspiHclkDiv12 Clock source: HCLK/12
** \arg QspiHclkDiv13 Clock source: HCLK/13
** \arg QspiHclkDiv14 Clock source: HCLK/14
** \arg QspiHclkDiv15 Clock source: HCLK/15
** \arg QspiHclkDiv16 Clock source: HCLK/16
** \arg QspiHclkDiv17 Clock source: HCLK/17
** \arg QspiHclkDiv18 Clock source: HCLK/18
** \arg QspiHclkDiv19 Clock source: HCLK/19
** \arg QspiHclkDiv20 Clock source: HCLK/20
** \arg QspiHclkDiv21 Clock source: HCLK/21
** \arg QspiHclkDiv22 Clock source: HCLK/22
** \arg QspiHclkDiv23 Clock source: HCLK/23
** \arg QspiHclkDiv24 Clock source: HCLK/24
** \arg QspiHclkDiv25 Clock source: HCLK/25
** \arg QspiHclkDiv26 Clock source: HCLK/26
** \arg QspiHclkDiv27 Clock source: HCLK/27
** \arg QspiHclkDiv28 Clock source: HCLK/28
** \arg QspiHclkDiv29 Clock source: HCLK/29
** \arg QspiHclkDiv30 Clock source: HCLK/30
** \arg QspiHclkDiv31 Clock source: HCLK/31
** \arg QspiHclkDiv32 Clock source: HCLK/32
** \arg QspiHclkDiv33 Clock source: HCLK/33
** \arg QspiHclkDiv34 Clock source: HCLK/34
** \arg QspiHclkDiv35 Clock source: HCLK/35
** \arg QspiHclkDiv36 Clock source: HCLK/36
** \arg QspiHclkDiv37 Clock source: HCLK/37
** \arg QspiHclkDiv38 Clock source: HCLK/38
** \arg QspiHclkDiv39 Clock source: HCLK/39
** \arg QspiHclkDiv40 Clock source: HCLK/40
** \arg QspiHclkDiv41 Clock source: HCLK/41
** \arg QspiHclkDiv42 Clock source: HCLK/42
** \arg QspiHclkDiv43 Clock source: HCLK/43
** \arg QspiHclkDiv44 Clock source: HCLK/44
** \arg QspiHclkDiv45 Clock source: HCLK/45
** \arg QspiHclkDiv46 Clock source: HCLK/46
** \arg QspiHclkDiv47 Clock source: HCLK/47
** \arg QspiHclkDiv48 Clock source: HCLK/48
** \arg QspiHclkDiv49 Clock source: HCLK/49
** \arg QspiHclkDiv50 Clock source: HCLK/50
** \arg QspiHclkDiv51 Clock source: HCLK/51
** \arg QspiHclkDiv52 Clock source: HCLK/52
** \arg QspiHclkDiv53 Clock source: HCLK/53
** \arg QspiHclkDiv54 Clock source: HCLK/54
** \arg QspiHclkDiv55 Clock source: HCLK/55
** \arg QspiHclkDiv56 Clock source: HCLK/56
** \arg QspiHclkDiv57 Clock source: HCLK/57
** \arg QspiHclkDiv58 Clock source: HCLK/58
** \arg QspiHclkDiv59 Clock source: HCLK/59
** \arg QspiHclkDiv60 Clock source: HCLK/60
** \arg QspiHclkDiv61 Clock source: HCLK/61
** \arg QspiHclkDiv62 Clock source: HCLK/62
** \arg QspiHclkDiv63 Clock source: HCLK/63
** \arg QspiHclkDiv64 Clock source: HCLK/64
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_SetClockDiv(en_qspi_clk_div_t enClkDiv)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_CLK_DIV(enClkDiv));
M4_QSPI->CR_f.DIV = enClkDiv;
return enRet;
}
/**
*******************************************************************************
** \brief Set WP Pin level
**
** \param [in] enWpLevel WP pin level
** \arg QspiWpPinOutputLow WP pin(QIO2) output low level
** \arg QspiWpPinOutputHigh WP pin(QIO2) output high level
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_SetWPPinLevel(en_qspi_wp_pin_level_t enWpLevel)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_WP_OUTPUT_LEVEL(enWpLevel));
M4_QSPI->FCR_f.WPOL = enWpLevel;
return enRet;
}
/**
*******************************************************************************
** \brief Set communication address width
**
** \param [in] enAddrWidth Communication address width
** \arg QspiAddressByteOne One byte address
** \arg QspiAddressByteTwo Two byte address
** \arg QspiAddressByteThree Three byte address
** \arg QspiAddressByteFour Four byte address
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_SetAddrWidth(en_qspi_addr_width_t enAddrWidth)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_INTERFACE_ADDR_WIDTH(enAddrWidth));
M4_QSPI->FCR_f.AWSL = enAddrWidth;
return enRet;
}
/**
*******************************************************************************
** \brief Set extend address value
**
** \param [in] u8Addr Extend address value
** \arg 0~0x3F
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_SetExtendAddress(uint8_t u8Addr)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_SET_EXTEND_ADDR(u8Addr));
M4_QSPI->EXAR_f.EXADR = u8Addr;
return enRet;
}
/**
*******************************************************************************
** \brief Set rom access instruction
**
** \param [in] u8Instr Rom access instruction
** \arg 0~0xFF
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_SetRomAccessInstruct(uint8_t u8Instr)
{
en_result_t enRet = Ok;
M4_QSPI->CCMD = u8Instr;
return enRet;
}
/**
*******************************************************************************
** \brief Write direct communication value
**
** \param [in] u8Val Direct communication value
** \arg 0~0xFF
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_WriteDirectCommValue(uint8_t u8Val)
{
en_result_t enRet = Ok;
M4_QSPI->DCOM = u8Val;
return enRet;
}
/**
*******************************************************************************
** \brief Read direct communication value
**
** \param [in] None
**
** \retval uint8_t Direct communication read value
**
******************************************************************************/
uint8_t QSPI_ReadDirectCommValue(void)
{
return ((uint8_t)M4_QSPI->DCOM);
}
/**
*******************************************************************************
** \brief Enable or disable xip mode
**
** \param [in] u8Instr Enable or disable xip mode instruction
** \arg 0~0xFF
**
** \param [in] enNewSta The function new state
** \arg Disable Disable xip mode
** \arg Enable Enable xip mode
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_XipModeCmd(uint8_t u8Instr, en_functional_state_t enNewSta)
{
en_result_t enRet = Ok;
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
M4_QSPI->XCMD = u8Instr;
if (Enable == enNewSta)
{
M4_QSPI->CR_f.XIPE = 1u;
}
else
{
M4_QSPI->CR_f.XIPE = 0u;
}
return enRet;
}
/**
*******************************************************************************
** \brief Enter direct communication mode
**
** \param [in] None
**
** \retval Ok Process successfully done
**
** \note If you are in XIP mode, you need to exit XIP mode and then start direct communication mode.
**
******************************************************************************/
en_result_t QSPI_EnterDirectCommMode(void)
{
en_result_t enRet = Ok;
M4_QSPI->CR_f.DCOME = 1u;
return enRet;
}
/**
*******************************************************************************
** \brief Exit direct communication mode
**
** \param [in] None
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t QSPI_ExitDirectCommMode(void)
{
en_result_t enRet = Ok;
M4_QSPI->CR_f.DCOME = 0u;
return enRet;
}
/**
*******************************************************************************
** \brief Get prefetch buffer current byte number
**
** \param [in] None
**
** \retval uint8_t Current buffer byte number
**
******************************************************************************/
uint8_t QSPI_GetPrefetchBufferNum(void)
{
return ((uint8_t)M4_QSPI->SR_f.PFNUM);
}
/**
*******************************************************************************
** \brief Get flag status
**
** \param [in] enFlag Choose need get status's flag
** \arg QspiFlagBusBusy QSPI bus work status flag in direct communication mode
** \arg QspiFlagXipMode XIP mode status signal
** \arg QspiFlagRomAccessError Trigger rom access error flag in direct communication mode
** \arg QspiFlagPrefetchBufferFull Prefetch buffer area status signal
** \arg QspiFlagPrefetchStop Prefetch action status signal
**
** \retval Set Flag is set
** \retval Reset Flag is reset
**
******************************************************************************/
en_flag_status_t QSPI_GetFlag(en_qspi_flag_type_t enFlag)
{
en_flag_status_t enFlagSta = Reset;
DDL_ASSERT(IS_VALID_GET_FLAG_TYPE(enFlag));
switch (enFlag)
{
case QspiFlagBusBusy:
enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.BUSY;
break;
case QspiFlagXipMode:
enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.XIPF;
break;
case QspiFlagRomAccessError:
enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.RAER;
break;
case QspiFlagPrefetchBufferFull:
enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.PFFUL;
break;
case QspiFlagPrefetchStop:
enFlagSta = (en_flag_status_t)M4_QSPI->SR_f.PFAN;
break;
default:
break;
}
return enFlagSta;
}
/**
*******************************************************************************
** \brief Clear flag status
**
** \param [in] enFlag Choose need get status's flag
** \arg QspiFlagRomAccessError Trigger rom access error flag in direct communication mode
**
** \retval Ok Process successfully done
** \retval ErrorInvalidParameter Parameter error
**
******************************************************************************/
en_result_t QSPI_ClearFlag(en_qspi_flag_type_t enFlag)
{
en_result_t enRet = Ok;
if (QspiFlagRomAccessError == enFlag)
{
M4_QSPI->SR2_f.RAERCLR = 1u;
}
else
{
enRet = ErrorInvalidParameter;
}
return enRet;
}
//@} // QspiGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,139 @@
/******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_rmu.c
**
** A detailed description is available at
** @link RmuGroup RMU description @endlink
**
** - 2018-10-28 CDT First version for Device Driver Library of RMU.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_rmu.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup RmuGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define ENABLE_RMU_REG_WRITE() (M4_SYSREG->PWR_FPRC = 0xa502u)
#define DISABLE_RMU_REG_WRITE() (M4_SYSREG->PWR_FPRC = 0xa500u)
#define RMU_FLAG_TIM ((uint16_t)0x1000u)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Get the chip reset cause.
**
** \param [in] pstcData Pointer to return reset cause structure.
**
** \retval Ok Get successfully.
**
******************************************************************************/
en_result_t RMU_GetResetCause(stc_rmu_rstcause_t *pstcData)
{
uint16_t u16RstCause = 0u;
stc_sysreg_rmu_rstf0_field_t *RMU_RSTF0_f = NULL;
if(NULL == pstcData)
{
return ErrorInvalidParameter;
}
u16RstCause = M4_SYSREG->RMU_RSTF0;
RMU_RSTF0_f = (stc_sysreg_rmu_rstf0_field_t *)(&u16RstCause);
pstcData->enMultiRst = (en_flag_status_t)(RMU_RSTF0_f->MULTIRF == 1u);
pstcData->enXtalErr = (en_flag_status_t)(RMU_RSTF0_f->XTALERF == 1u);
pstcData->enClkFreqErr = (en_flag_status_t)(RMU_RSTF0_f->CKFERF == 1u);
pstcData->enRamEcc = (en_flag_status_t)(RMU_RSTF0_f->RAECRF == 1u);
pstcData->enRamParityErr = (en_flag_status_t)(RMU_RSTF0_f->RAPERF == 1u);
pstcData->enMpuErr = (en_flag_status_t)(RMU_RSTF0_f->MPUERF == 1u);
pstcData->enSoftware = (en_flag_status_t)(RMU_RSTF0_f->SWRF == 1u);
pstcData->enPowerDown = (en_flag_status_t)(RMU_RSTF0_f->PDRF == 1u);
pstcData->enSwdt = (en_flag_status_t)(RMU_RSTF0_f->SWDRF == 1u);
pstcData->enWdt = (en_flag_status_t)(RMU_RSTF0_f->WDRF == 1u);
pstcData->enPvd2 = (en_flag_status_t)(RMU_RSTF0_f->PVD2RF == 1u);
pstcData->enPvd1 = (en_flag_status_t)(RMU_RSTF0_f->PVD2RF == 1u);
pstcData->enBrownOut = (en_flag_status_t)(RMU_RSTF0_f->BORF == 1u);
pstcData->enRstPin = (en_flag_status_t)(RMU_RSTF0_f->PINRF == 1u);
pstcData->enPowerOn = (en_flag_status_t)(RMU_RSTF0_f->PORF == 1u);
return Ok;
}
/**
*******************************************************************************
** \brief Clear the reset flag.
**
** \param None
**
** \retval Ok Clear successfully.
**
** \note clear reset flag should be done after read RMU_RSTF0 register.
******************************************************************************/
en_result_t RMU_ClrResetFlag(void)
{
uint16_t u16status = 0u;
uint32_t u32timeout = 0u;
ENABLE_RMU_REG_WRITE();
do
{
u32timeout++;
M4_SYSREG->RMU_RSTF0_f.CLRF = 1u;
u16status = M4_SYSREG->RMU_RSTF0;
}while((u32timeout != RMU_FLAG_TIM) && u16status);
DISABLE_RMU_REG_WRITE();
if(u32timeout >= RMU_FLAG_TIM)
{
return ErrorTimeout;
}
return Ok;
}
//@} // RmuGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,974 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_rtc.c
**
** A detailed description is available at
** @link RtcGroup Real-Time Clock description @endlink
**
** - 2018-11-22 CDT First version for Device Driver Library of RTC.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_rtc.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup RtcGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter valid check for clock source type */
#define IS_VALID_CLK_SOURCE_TYPE(x) \
( (RtcClkXtal32 == (x)) || \
(RtcClkLrc == (x)))
/*!< Parameter valid check for period interrupt condition */
#define IS_VALID_PERIOD_INT_CONDITION(x) \
( (RtcPeriodIntInvalid == (x)) || \
(RtcPeriodIntHalfSec == (x)) || \
(RtcPeriodIntOneSec == (x)) || \
(RtcPeriodIntOneMin == (x)) || \
(RtcPeriodIntOneHour == (x)) || \
(RtcPeriodIntOneDay == (x)) || \
(RtcPeriodIntOneMon == (x)))
/*!< Parameter valid check for time format */
#define IS_VALID_TIME_FORMAT(x) \
( (RtcTimeFormat12Hour == (x)) || \
(RtcTimeFormat24Hour == (x)))
/*!< Parameter valid check for compensation way */
#define IS_VALID_COMPEN_WAY(x) \
( (RtcOutputCompenDistributed == (x)) || \
(RtcOutputCompenUniform == (x)))
/*!< Parameter valid check for compensation value range */
#define IS_VALID_COMPEN_VALUE_RANGE(x) ((x) <= 0x1FFu)
/*!< Parameter valid check for data format */
#define IS_VALID_DATA_FORMAT(x) \
( (RtcDataFormatDec == (x)) || \
(RtcDataFormatBcd == (x)))
/*!< Parameter valid check for time second */
#define IS_VALID_TIME_SECOND(x) ((x) <= 59u)
/*!< Parameter valid check for time minute */
#define IS_VALID_TIME_MINUTE(x) ((x) <= 59u)
/*!< Parameter valid check for time hour */
#define IS_VALID_TIME_HOUR12(x) (((x) >= 1u) && ((x) <= 12u))
#define IS_VALID_TIME_HOUR24(x) ((x) <= 23u)
/*!< Parameter valid check for date weekday */
#define IS_VALID_DATE_WEEKDAY(x) ((x) <= 6u)
/*!< Parameter valid check for date day */
#define IS_VALID_DATE_DAY(x) (((x) >= 1u) && ((x) <= 31u))
/*!< Parameter valid check for date month */
#define IS_VALID_DATE_MONTH(x) (((x) >= 1u) && ((x) <= 12u))
/*!< Parameter valid check for date year */
#define IS_VALID_DATE_YEAR(x) ((x) <= 99u)
/*!< Parameter valid check for hour12 am/pm */
#define IS_VALID_HOUR12_AMPM(x) \
( (RtcHour12Am == (x)) || \
(RtcHour12Pm == (x)))
/*!< Parameter valid check for alarm weekday */
#define IS_VALID_ALARM_WEEKDAY(x) (((x) >= 1u) && ((x) <= 0x7Fu))
/*!< Parameter valid check for interrupt request type */
#define IS_VALID_IRQ_TYPE(x) \
( (RtcIrqPeriod == (x)) || \
(RtcIrqAlarm == (x)))
/*!< 12 hour format am/pm status bit */
#define RTC_HOUR12_AMPM_MASK (0x20u)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief De-Initialize RTC
**
** \param [in] None
**
** \retval Ok Process successfully done
** \retval ErrorTimeout De-Initialize timeout
**
******************************************************************************/
en_result_t RTC_DeInit(void)
{
uint8_t u8RegSta;
uint32_t u32Timeout, u32TimeCnt = 0u;
en_result_t enRet = Ok;
M4_RTC->CR0_f.RESET = 0u;
/* Waiting for normal count status or end of RTC software reset */
u32Timeout = SystemCoreClock >> 8u;
do
{
u8RegSta = (uint8_t)M4_RTC->CR0_f.RESET;
u32TimeCnt++;
} while ((u32TimeCnt < u32Timeout) && (u8RegSta == 1u));
if (1u == u8RegSta)
{
enRet = ErrorTimeout;
}
else
{
/* Initialize all RTC registers */
M4_RTC->CR0_f.RESET = 1u;
}
return enRet;
}
/**
*******************************************************************************
** \brief Initialize RTC
**
** \param [in] pstcRtcInit Pointer to RTC init configuration
** \arg See the struct #stc_rtc_init_t
**
** \retval Ok Process successfully done
** \retval Error Parameter error
**
******************************************************************************/
en_result_t RTC_Init(const stc_rtc_init_t *pstcRtcInit)
{
en_result_t enRet = Ok;
if (NULL == pstcRtcInit)
{
enRet = Error;
}
else
{
/* Check parameters */
DDL_ASSERT(IS_VALID_CLK_SOURCE_TYPE(pstcRtcInit->enClkSource));
DDL_ASSERT(IS_VALID_PERIOD_INT_CONDITION(pstcRtcInit->enPeriodInt));
DDL_ASSERT(IS_VALID_TIME_FORMAT(pstcRtcInit->enTimeFormat));
DDL_ASSERT(IS_VALID_COMPEN_WAY(pstcRtcInit->enCompenWay));
DDL_ASSERT(IS_VALID_COMPEN_VALUE_RANGE(pstcRtcInit->u16CompenVal));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcRtcInit->enCompenEn));
/* Configure clock */
if (RtcClkLrc == pstcRtcInit->enClkSource)
{
M4_RTC->CR3_f.LRCEN = 1u;
}
M4_RTC->CR3_f.RCKSEL = pstcRtcInit->enClkSource;
/* Configure control register */
M4_RTC->CR1_f.PRDS = pstcRtcInit->enPeriodInt;
M4_RTC->CR1_f.AMPM = pstcRtcInit->enTimeFormat;
M4_RTC->CR1_f.ONEHZSEL = pstcRtcInit->enCompenWay;
/* Configure clock error compensation register */
M4_RTC->ERRCRH_f.COMP8 = ((uint32_t)pstcRtcInit->u16CompenVal >> 8u) & 0x01u;
M4_RTC->ERRCRL = (uint32_t)pstcRtcInit->u16CompenVal & 0x00FFu;
M4_RTC->ERRCRH_f.COMPEN = pstcRtcInit->enCompenEn;
}
return enRet;
}
/**
*******************************************************************************
** \brief Enter RTC read/write mode
**
** \param [in] None
**
** \retval Ok Process successfully done
** \retval ErrorTimeout Enter mode timeout
**
******************************************************************************/
en_result_t RTC_EnterRwMode(void)
{
uint8_t u8RegSta;
uint32_t u32Timeout, u32TimeCnt = 0u;
en_result_t enRet = Ok;
/* Mode switch when RTC is running */
if (0u != M4_RTC->CR1_f.START)
{
M4_RTC->CR2_f.RWREQ = 1u;
/* Waiting for RWEN bit set */
u32Timeout = SystemCoreClock >> 8u;
do
{
u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
u32TimeCnt++;
} while ((u32TimeCnt < u32Timeout) && (u8RegSta == 0u));
if (0u == u8RegSta)
{
enRet = ErrorTimeout;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Exit RTC read/write mode
**
** \param [in] None
**
** \retval Ok Process successfully done
** \retval ErrorTimeout Exit mode timeout
**
******************************************************************************/
en_result_t RTC_ExitRwMode(void)
{
uint8_t u8RegSta;
uint32_t u32Timeout, u32TimeCnt = 0u;
en_result_t enRet = Ok;
/* Mode switch when RTC is running */
if (0u != M4_RTC->CR1_f.START)
{
M4_RTC->CR2_f.RWREQ = 0u;
/* Waiting for RWEN bit reset */
u32Timeout = SystemCoreClock >> 8u;
do
{
u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
u32TimeCnt++;
} while ((u32TimeCnt < u32Timeout) && (u8RegSta == 1u));
if (1u == u8RegSta)
{
enRet = ErrorTimeout;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable RTC count
**
** \param [in] enNewSta The function new state
** \arg Disable Disable RTC count
** \arg Enable Enable RTC count
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t RTC_Cmd(en_functional_state_t enNewSta)
{
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
M4_RTC->CR1_f.START = enNewSta;
return enRet;
}
/**
*******************************************************************************
** \brief RTC period interrupt config
**
** \param [in] enIntType Period interrupt request type
** \arg RtcPeriodIntInvalid Period interrupt invalid
** \arg RtcPeriodIntHalfSec 0.5 second period interrupt
** \arg RtcPeriodIntOneSec 1 second period interrupt
** \arg RtcPeriodIntOneMin 1 minute period interrupt
** \arg RtcPeriodIntOneHour 1 hour period interrupt
** \arg RtcPeriodIntOneDay 1 day period interrupt
** \arg RtcPeriodIntOneMon 1 month period interrupt
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t RTC_PeriodIntConfig(en_rtc_period_int_type_t enIntType)
{
uint8_t u8RtcSta;
uint8_t u8IntSta;
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_VALID_PERIOD_INT_CONDITION(enIntType));
u8RtcSta = (uint8_t)M4_RTC->CR1_f.START;
u8IntSta = (uint8_t)M4_RTC->CR2_f.PRDIE;
/* Disable period interrupt when START=1 and PRDIE=1 */
if ((1u == u8IntSta) && (1u == u8RtcSta))
{
M4_RTC->CR2_f.PRDIE = 0u;
}
M4_RTC->CR1_f.PRDS = enIntType;
if ((1u == u8IntSta) && (1u == u8RtcSta))
{
M4_RTC->CR2_f.PRDIE = 1u;
}
return enRet;
}
/**
*******************************************************************************
** \brief RTC switch to low power mode
**
** \param [in] None
**
** \retval Ok Process successfully done
** \retval ErrorInvalidMode RTC count not start
** \retval ErrorTimeout Switch timeout
**
******************************************************************************/
en_result_t RTC_LowPowerSwitch(void)
{
uint8_t u8RegSta;
uint32_t u32Timeout, u32TimeCnt = 0u;
en_result_t enRet = ErrorInvalidMode;
/* Check RTC work status */
if (0u != M4_RTC->CR1_f.START)
{
M4_RTC->CR2_f.RWREQ = 1u;
/* Waiting for RTC RWEN bit set */
u32Timeout = SystemCoreClock / 100u;
do
{
u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
u32TimeCnt++;
} while ((u32TimeCnt < u32Timeout) && (u8RegSta == 0u));
if (0u == u8RegSta)
{
enRet = ErrorTimeout;
}
else
{
M4_RTC->CR2_f.RWREQ = 0u;
/* Waiting for RTC RWEN bit reset */
u32TimeCnt = 0u;
do
{
u8RegSta = (uint8_t)M4_RTC->CR2_f.RWEN;
u32TimeCnt++;
} while ((u32TimeCnt < u32Timeout) && (u8RegSta == 1u));
if (1u == u8RegSta)
{
enRet = ErrorTimeout;
}
else
{
enRet = Ok;
}
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Set RTC 1hz output compensation value
**
** \param [in] u16CompenVal Clock compensation value
** \arg 0~0x1FF
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t RTC_SetClkCompenValue(uint16_t u16CompenVal)
{
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_VALID_COMPEN_VALUE_RANGE(u16CompenVal));
M4_RTC->ERRCRH_f.COMP8 = ((uint32_t)u16CompenVal >> 8u) & 0x01u;
M4_RTC->ERRCRL = (uint32_t)u16CompenVal & 0x00FFu;
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable clock compensation
**
** \param [in] enNewSta The function new state
** \arg Disable Disable RTC clock compensation
** \arg Enable Enable RTC clock compensation
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t RTC_ClkCompenCmd(en_functional_state_t enNewSta)
{
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
M4_RTC->ERRCRH_f.COMPEN = enNewSta;
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable RTC 1hz output
**
** \param [in] enNewSta The function new state
** \arg Disable Disable RTC 1hz output
** \arg Enable Enable RTC 1hz output
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t RTC_OneHzOutputCmd(en_functional_state_t enNewSta)
{
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
M4_RTC->CR1_f.ONEHZOE = enNewSta;
return enRet;
}
/**
*******************************************************************************
** \brief Set RTC current date and time
**
** \param [in] enFormat Date and time data format
** \arg RtcDataFormatDec Decimal format
** \arg RtcDataFormatBcd BCD format
**
** \param [in] pstcRtcDateTime Pointer to RTC date and time configuration
** \arg See the struct #stc_rtc_date_time_t
**
** \param [in] enUpdateDateEn The function new state(Contain year/month/day/weekday)
** \arg Disable Disable update RTC date
** \arg Enable Enable update RTC date
**
** \param [in] enUpdateTimeEn The function new state(Contain hour/minute/second)
** \arg Disable Disable update RTC time
** \arg Enable Enable update RTC time
**
** \retval Ok Process successfully done
** \retval Error Enter or exit read/write mode failed
** \retval ErrorInvalidParameter Parameter enUpdateDateEn or enUpdateTimeEn invalid
**
******************************************************************************/
en_result_t RTC_SetDateTime(en_rtc_data_format_t enFormat, const stc_rtc_date_time_t *pstcRtcDateTime,
en_functional_state_t enUpdateDateEn, en_functional_state_t enUpdateTimeEn)
{
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enUpdateDateEn));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enUpdateTimeEn));
/* Check update status */
if (((Disable == enUpdateDateEn) && (Disable == enUpdateTimeEn)) || (NULL == pstcRtcDateTime))
{
enRet = ErrorInvalidParameter;
}
else
{
/* Check the date parameters */
if (Enable == enUpdateDateEn)
{
if (RtcDataFormatDec == enFormat)
{
DDL_ASSERT(IS_VALID_DATE_YEAR(pstcRtcDateTime->u8Year));
DDL_ASSERT(IS_VALID_DATE_MONTH(pstcRtcDateTime->u8Month));
DDL_ASSERT(IS_VALID_DATE_DAY(pstcRtcDateTime->u8Day));
}
else
{
DDL_ASSERT(IS_VALID_DATE_YEAR(BCD2DEC(pstcRtcDateTime->u8Year)));
DDL_ASSERT(IS_VALID_DATE_MONTH(BCD2DEC(pstcRtcDateTime->u8Month)));
DDL_ASSERT(IS_VALID_DATE_DAY(BCD2DEC(pstcRtcDateTime->u8Day)));
}
DDL_ASSERT(IS_VALID_DATE_WEEKDAY(pstcRtcDateTime->u8Weekday));
}
/* Check the time parameters */
if (Enable == enUpdateTimeEn)
{
if (RtcDataFormatDec == enFormat)
{
if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
{
DDL_ASSERT(IS_VALID_TIME_HOUR12(pstcRtcDateTime->u8Hour));
DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcDateTime->enAmPm));
}
else
{
DDL_ASSERT(IS_VALID_TIME_HOUR24(pstcRtcDateTime->u8Hour));
}
DDL_ASSERT(IS_VALID_TIME_MINUTE(pstcRtcDateTime->u8Minute));
DDL_ASSERT(IS_VALID_TIME_SECOND(pstcRtcDateTime->u8Second));
}
else
{
if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
{
DDL_ASSERT(IS_VALID_TIME_HOUR12(BCD2DEC(pstcRtcDateTime->u8Hour)));
DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcDateTime->enAmPm));
}
else
{
DDL_ASSERT(IS_VALID_TIME_HOUR24(BCD2DEC(pstcRtcDateTime->u8Hour)));
}
DDL_ASSERT(IS_VALID_TIME_MINUTE(BCD2DEC(pstcRtcDateTime->u8Minute)));
DDL_ASSERT(IS_VALID_TIME_SECOND(BCD2DEC(pstcRtcDateTime->u8Second)));
}
}
/* Enter read/write mode */
if (RTC_EnterRwMode() == ErrorTimeout)
{
enRet = Error;
}
else
{
/* Update date */
if (Enable == enUpdateDateEn)
{
if (RtcDataFormatDec == enFormat)
{
M4_RTC->YEAR = DEC2BCD((uint32_t)pstcRtcDateTime->u8Year);
M4_RTC->MON = DEC2BCD((uint32_t)pstcRtcDateTime->u8Month);
M4_RTC->DAY = DEC2BCD((uint32_t)pstcRtcDateTime->u8Day);
}
else
{
M4_RTC->YEAR = pstcRtcDateTime->u8Year;
M4_RTC->MON = pstcRtcDateTime->u8Month;
M4_RTC->DAY = pstcRtcDateTime->u8Day;
}
M4_RTC->WEEK = pstcRtcDateTime->u8Weekday;
}
/* Update time */
if (Enable == enUpdateTimeEn)
{
if (RtcDataFormatDec == enFormat)
{
if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
(RtcHour12Pm == pstcRtcDateTime->enAmPm))
{
M4_RTC->HOUR = DEC2BCD((uint32_t)pstcRtcDateTime->u8Hour) | RTC_HOUR12_AMPM_MASK;
}
else
{
M4_RTC->HOUR = DEC2BCD((uint32_t)pstcRtcDateTime->u8Hour);
}
M4_RTC->MIN = DEC2BCD((uint32_t)pstcRtcDateTime->u8Minute);
M4_RTC->SEC = DEC2BCD((uint32_t)pstcRtcDateTime->u8Second);
}
else
{
if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
(RtcHour12Pm == pstcRtcDateTime->enAmPm))
{
M4_RTC->HOUR = (uint32_t)pstcRtcDateTime->u8Hour | RTC_HOUR12_AMPM_MASK;
}
else
{
M4_RTC->HOUR = (uint32_t)pstcRtcDateTime->u8Hour;
}
M4_RTC->MIN = pstcRtcDateTime->u8Minute;
M4_RTC->SEC = pstcRtcDateTime->u8Second;
}
}
/* Exit read/write mode */
if (RTC_ExitRwMode() == ErrorTimeout)
{
enRet = Error;
}
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Get RTC current date and time
**
** \param [in] enFormat Date and time data format
** \arg RtcDataFormatDec Decimal format
** \arg RtcDataFormatBcd BCD format
**
** \param [out] pstcRtcDateTime Pointer to RTC date and time configuration
** \arg See the struct #stc_rtc_date_time_t
**
** \retval Ok Process successfully done
** \retval Error Enter or exit read/write mode failed
**
******************************************************************************/
en_result_t RTC_GetDateTime(en_rtc_data_format_t enFormat, stc_rtc_date_time_t *pstcRtcDateTime)
{
en_result_t enRet = Ok;
if(NULL == pstcRtcDateTime)
{
enRet = Error;
}
else
{
/* Check parameters */
DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
/* Enter read/write mode */
if (RTC_EnterRwMode() == ErrorTimeout)
{
enRet = Error;
}
else
{
/* Get RTC date and time registers */
pstcRtcDateTime->u8Year = (uint8_t)(M4_RTC->YEAR);
pstcRtcDateTime->u8Month = (uint8_t)(M4_RTC->MON);
pstcRtcDateTime->u8Day = (uint8_t)(M4_RTC->DAY);
pstcRtcDateTime->u8Weekday = (uint8_t)(M4_RTC->WEEK);
pstcRtcDateTime->u8Hour = (uint8_t)(M4_RTC->HOUR);
pstcRtcDateTime->u8Minute = (uint8_t)(M4_RTC->MIN);
pstcRtcDateTime->u8Second = (uint8_t)(M4_RTC->SEC);
if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
{
if (RTC_HOUR12_AMPM_MASK == (pstcRtcDateTime->u8Hour & RTC_HOUR12_AMPM_MASK))
{
pstcRtcDateTime->u8Hour &= (uint8_t)(~RTC_HOUR12_AMPM_MASK);
pstcRtcDateTime->enAmPm = RtcHour12Pm;
}
else
{
pstcRtcDateTime->enAmPm = RtcHour12Am;
}
}
/* Check decimal format*/
if (RtcDataFormatDec == enFormat)
{
pstcRtcDateTime->u8Year = BCD2DEC(pstcRtcDateTime->u8Year);
pstcRtcDateTime->u8Month = BCD2DEC(pstcRtcDateTime->u8Month);
pstcRtcDateTime->u8Day = BCD2DEC(pstcRtcDateTime->u8Day);
pstcRtcDateTime->u8Hour = BCD2DEC(pstcRtcDateTime->u8Hour);
pstcRtcDateTime->u8Minute = BCD2DEC(pstcRtcDateTime->u8Minute);
pstcRtcDateTime->u8Second = BCD2DEC(pstcRtcDateTime->u8Second);
}
/* exit read/write mode */
if (RTC_ExitRwMode() == ErrorTimeout)
{
enRet = Error;
}
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Set RTC alarm time
**
** \param [in] enFormat Date and time data format
** \arg RtcDataFormatDec Decimal format
** \arg RtcDataFormatBcd BCD format
**
** \param [in] pstcRtcAlarmTime Pointer to RTC alarm time configuration
** \arg See the struct #stc_rtc_alarm_time_t
**
** \retval Ok Process successfully done
** \retval Error Parameter error
**
******************************************************************************/
en_result_t RTC_SetAlarmTime(en_rtc_data_format_t enFormat, const stc_rtc_alarm_time_t *pstcRtcAlarmTime)
{
en_result_t enRet = Ok;
if (NULL == pstcRtcAlarmTime)
{
enRet = Error;
}
else
{
/* Check parameters */
DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
if (RtcDataFormatDec == enFormat)
{
if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
{
DDL_ASSERT(IS_VALID_TIME_HOUR12(pstcRtcAlarmTime->u8Hour));
DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcAlarmTime->enAmPm));
}
else
{
DDL_ASSERT(IS_VALID_TIME_HOUR24(pstcRtcAlarmTime->u8Hour));
}
DDL_ASSERT(IS_VALID_TIME_MINUTE(pstcRtcAlarmTime->u8Minute));
}
else
{
if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
{
DDL_ASSERT(IS_VALID_TIME_HOUR12(BCD2DEC(pstcRtcAlarmTime->u8Hour)));
DDL_ASSERT(IS_VALID_HOUR12_AMPM(pstcRtcAlarmTime->enAmPm));
}
else
{
DDL_ASSERT(IS_VALID_TIME_HOUR24(BCD2DEC(pstcRtcAlarmTime->u8Hour)));
}
DDL_ASSERT(IS_VALID_TIME_MINUTE(BCD2DEC(pstcRtcAlarmTime->u8Minute)));
}
DDL_ASSERT(IS_VALID_ALARM_WEEKDAY(pstcRtcAlarmTime->u8Weekday));
/* Configure alarm registers */
if (RtcDataFormatDec == enFormat)
{
if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
(RtcHour12Pm == pstcRtcAlarmTime->enAmPm))
{
M4_RTC->ALMHOUR = DEC2BCD((uint32_t)pstcRtcAlarmTime->u8Hour) | RTC_HOUR12_AMPM_MASK;
}
else
{
M4_RTC->ALMHOUR = DEC2BCD((uint32_t)pstcRtcAlarmTime->u8Hour);
}
M4_RTC->ALMMIN = DEC2BCD((uint32_t)pstcRtcAlarmTime->u8Minute);
}
else
{
if ((RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM) &&
(RtcHour12Pm == pstcRtcAlarmTime->enAmPm))
{
M4_RTC->ALMHOUR = (uint32_t)pstcRtcAlarmTime->u8Hour | RTC_HOUR12_AMPM_MASK;
}
else
{
M4_RTC->ALMHOUR = (uint32_t)pstcRtcAlarmTime->u8Hour;
}
M4_RTC->ALMMIN = pstcRtcAlarmTime->u8Minute;
}
M4_RTC->ALMWEEK = pstcRtcAlarmTime->u8Weekday;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get RTC alarm time
**
** \param [in] enFormat Date and time data format
** \arg RtcDataFormatDec Decimal format
** \arg RtcDataFormatBcd BCD format
**
** \param [out] pstcRtcAlarmTime Pointer to RTC alarm time configuration
** \arg See the struct #stc_rtc_alarm_time_t
**
** \retval Ok Process successfully done
** \retval Error Parameter error
**
******************************************************************************/
en_result_t RTC_GetAlarmTime(en_rtc_data_format_t enFormat, stc_rtc_alarm_time_t *pstcRtcAlarmTime)
{
en_result_t enRet = Ok;
if(NULL == pstcRtcAlarmTime)
{
enRet = Error;
}
else
{
/* Check parameters */
DDL_ASSERT(IS_VALID_DATA_FORMAT(enFormat));
/* Get RTC date and time register */
pstcRtcAlarmTime->u8Weekday = (uint8_t)M4_RTC->ALMWEEK;
pstcRtcAlarmTime->u8Minute = (uint8_t)M4_RTC->ALMMIN;
pstcRtcAlarmTime->u8Hour = (uint8_t)M4_RTC->ALMHOUR;
if (RtcTimeFormat12Hour == M4_RTC->CR1_f.AMPM)
{
if ((pstcRtcAlarmTime->u8Hour & RTC_HOUR12_AMPM_MASK) == RTC_HOUR12_AMPM_MASK)
{
pstcRtcAlarmTime->u8Hour &= (uint8_t)(~RTC_HOUR12_AMPM_MASK);
pstcRtcAlarmTime->enAmPm = RtcHour12Pm;
}
else
{
pstcRtcAlarmTime->enAmPm = RtcHour12Am;
}
}
/* Check decimal format*/
if (RtcDataFormatDec == enFormat)
{
pstcRtcAlarmTime->u8Hour = BCD2DEC(pstcRtcAlarmTime->u8Hour);
pstcRtcAlarmTime->u8Minute = BCD2DEC(pstcRtcAlarmTime->u8Minute);
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable RTC alarm function
**
** \param [in] enNewSta The function new state
** \arg Disable Disable RTC alarm function
** \arg Enable Enable RTC alarm function
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t RTC_AlarmCmd(en_functional_state_t enNewSta)
{
uint8_t u8RtcSta;
uint8_t u8IntSta;
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
u8RtcSta = (uint8_t)M4_RTC->CR1_f.START;
u8IntSta = (uint8_t)M4_RTC->CR2_f.ALMIE;
/* Disable alarm interrupt and clear alarm flag when START=1 and ALMIE=1 */
if ((1u == u8IntSta) && (1u == u8RtcSta))
{
M4_RTC->CR2_f.ALMIE = 0u;
}
M4_RTC->CR2_f.ALME = enNewSta;
if ((1u == u8IntSta) && (1u == u8RtcSta))
{
M4_RTC->CR1_f.ALMFCLR = 0u;
M4_RTC->CR2_f.ALMIE = u8IntSta;
}
return enRet;
}
/**
*******************************************************************************
** \brief Enable or disable RTC interrupt request
**
** \param [in] enIrq RTC interrupt request type
** \arg RtcIrqPeriod Period count interrupt request
** \arg RtcIrqAlarm Alarm interrupt request
**
** \param [in] enNewSta The function new state
** \arg Disable Disable interrupt request
** \arg Enable Enable interrupt request
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t RTC_IrqCmd(en_rtc_irq_type_t enIrq, en_functional_state_t enNewSta)
{
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_VALID_IRQ_TYPE(enIrq));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewSta));
/* enable/disable interrupt */
switch (enIrq)
{
case RtcIrqPeriod:
M4_RTC->CR2_f.PRDIE = enNewSta;
break;
case RtcIrqAlarm:
M4_RTC->CR2_f.ALMIE = enNewSta;
break;
default:
break;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get RTC Alarm flag status
**
** \param [in] None
**
** \retval Set Flag is set
** \retval Reset Flag is reset
**
******************************************************************************/
en_flag_status_t RTC_GetAlarmFlag(void)
{
return (en_flag_status_t)(M4_RTC->CR2_f.ALMF);
}
/**
*******************************************************************************
** \brief Clear RTC Alarm flag status
**
** \param [in] None
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t RTC_ClearAlarmFlag(void)
{
en_result_t enRet = Ok;
M4_RTC->CR1_f.ALMFCLR = 0u;
return enRet;
}
//@} // RtcGroup
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,282 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_sram.c
**
** A detailed description is available at
** @link SramGroup Internal SRAM module description @endlink
**
** - 2018-10-17 CDT First version for Device Driver Library of SRAM.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_sram.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup SramGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*! Parameter validity check for ECC/Parity error handling. */
#define IS_VALID_ERR_OP(x) \
( ((x) == SramNmi) || \
((x) == SramReset))
/*! Parameter validity check for SRAM ECC mode */
#define IS_VALID_ECC_MD(x) \
( ((x) == EccMode0) || \
((x) == EccMode1) || \
((x) == EccMode2) || \
((x) == EccMode3))
/*! Parameter validity check for SRAM Index */
#define IS_VALID_INDEX(x) \
( ((x) == Sram12Idx) || \
((x) == Sram3Idx) || \
((x) == SramHsIdx) || \
((x) == SramRetIdx))
/*! Parameter validity check for SRAM R/W wait cycle */
#define IS_VALID_WAIT_CYCLE(x) \
( ((x) == SramCycle1) || \
((x) == SramCycle2) || \
((x) == SramCycle3) || \
((x) == SramCycle4) || \
((x) == SramCycle5) || \
((x) == SramCycle6) || \
((x) == SramCycle7) || \
((x) == SramCycle8))
/*! Parameter validity check for SRAM error status */
#define IS_VALID_ERR(x) \
( ((x) == Sram3EccErr1) || \
((x) == Sram3EccErr2) || \
((x) == Sram12ParityErr) || \
((x) == SramHSParityErr) || \
((x) == SramRetParityErr))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief SRAM read, write wait cycle register disable function
**
** \param None
**
** \retval Ok SRAM R/W wait cycle register disabled
**
******************************************************************************/
en_result_t SRAM_WT_Disable(void)
{
M4_SRAMC->WTPR = 0x76u;
return Ok;
}
/**
*******************************************************************************
** \brief SRAM read, write wait cycle register enable function
**
** \param None
**
** \retval Ok SRAM R/W wait cycle register enabled
**
******************************************************************************/
en_result_t SRAM_WT_Enable(void)
{
M4_SRAMC->WTPR = 0x77u;
return Ok;
}
/**
*******************************************************************************
** \brief SRAM ECC/Parity check register disable function
**
** \param None
**
** \retval Ok SRAM ECC/Parity check register disabled
**
******************************************************************************/
en_result_t SRAM_CK_Disable(void)
{
M4_SRAMC->CKPR = 0x76u;
return Ok;
}
/**
*******************************************************************************
** \brief SRAM ECC/Parity check register enable function
**
** \param None
**
** \retval Ok SRAM ECC/Parity check register enabled
**
******************************************************************************/
en_result_t SRAM_CK_Enable(void)
{
M4_SRAMC->CKPR = 0x77u;
return Ok;
}
/**
*******************************************************************************
** \brief Get SRAM ECC/Parity error status flag
**
** \param [in] enSramErrStatus SRAM error status, This parameter can be
** some values of @ref en_sram_err_status_t
**
** \retval Set Corresponding error occurs
** Reset Corresponding error not occurs
**
******************************************************************************/
en_flag_status_t SRAM_GetStatus(en_sram_err_status_t enSramErrStatus)
{
DDL_ASSERT(IS_VALID_ERR(enSramErrStatus));
if (true == !!(enSramErrStatus & M4_SRAMC->CKSR))
{
return Set;
}
else
{
return Reset;
}
}
/**
*******************************************************************************
** \brief Clear SRAM ECC/Parity error status flag
**
** \param [in] enSramErrStatus SRAM error status, This parameter can be
** some values of @ref en_sram_err_status_t
**
** \retval Ok Corresponding error flag be cleared
** ErrorInvalidParameter Invalid parameter
**
******************************************************************************/
en_result_t SRAM_ClrStatus(en_sram_err_status_t enSramErrStatus)
{
DDL_ASSERT(IS_VALID_ERR(enSramErrStatus));
M4_SRAMC->CKSR |= enSramErrStatus;
return Ok;
}
/**
*******************************************************************************
** \brief SRAM initialization
**
** \param [in] pstcSramConfig SRAM configure structure
**
** \retval Ok SRAM initialized
** ErrorInvalidParameter Invalid parameter
**
******************************************************************************/
en_result_t SRAM_Init(const stc_sram_config_t *pstcSramConfig)
{
uint8_t i = 0u;
uint8_t u8TmpIdx;
en_result_t enRet = Ok;
DDL_ASSERT(IS_VALID_WAIT_CYCLE(pstcSramConfig->enSramRC));
DDL_ASSERT(IS_VALID_WAIT_CYCLE(pstcSramConfig->enSramWC));
DDL_ASSERT(IS_VALID_ECC_MD(pstcSramConfig->enSramEccMode));
DDL_ASSERT(IS_VALID_ERR_OP(pstcSramConfig->enSramEccOp));
DDL_ASSERT(IS_VALID_ERR_OP(pstcSramConfig->enSramPyOp));
u8TmpIdx = pstcSramConfig->u8SramIdx;
if (0u == u8TmpIdx)
{
enRet = ErrorInvalidParameter;
}
else
{
SRAM_WT_Enable();
SRAM_CK_Enable();
for (i = 0u; i < 4u; i++)
{
if (true == (u8TmpIdx & 0x01u))
{
M4_SRAMC->WTCR |= (pstcSramConfig->enSramRC | \
(pstcSramConfig->enSramWC << 4ul)) << (i * 8ul);
}
u8TmpIdx >>= 1u;
}
/* SRAM3 ECC config */
if (pstcSramConfig->u8SramIdx & Sram3Idx)
{
M4_SRAMC->CKCR_f.ECCMOD = pstcSramConfig->enSramEccMode;
M4_SRAMC->CKCR_f.ECCOAD = pstcSramConfig->enSramEccOp;
}
/* SRAM1/2/HS/Ret parity config */
else
{
M4_SRAMC->CKCR_f.PYOAD = pstcSramConfig->enSramPyOp;
}
SRAM_WT_Disable();
SRAM_CK_Disable();
}
return enRet;
}
/**
*******************************************************************************
** \brief SRAM de-initialization
**
** \param None
**
** \retval Ok SRAM de-initialized
**
******************************************************************************/
en_result_t SRAM_DeInit(void)
{
/* SRAM R/W wait register */
M4_SRAMC->WTPR = 0x77ul;
M4_SRAMC->WTCR = 0ul;
M4_SRAMC->WTPR = 0x76ul;
/* SRAM check register */
M4_SRAMC->CKPR = 0x77ul;
M4_SRAMC->CKCR = 0ul;
M4_SRAMC->CKPR = 0x76ul;
/* SRAM status register */
M4_SRAMC->CKSR = 0x1Ful;
return Ok;
}
//@} // SramGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,166 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_swdt.c
**
** A detailed description is available at
** @link SwdtGroup Special Watchdog Counter description @endlink
**
** - 2018-10-16 CDT First version for Device Driver Library of SWDT.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_swdt.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup SwdtGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter valid check for flag type */
#define IS_VALID_FLAG_TYPE(x) \
( (SwdtFlagCountUnderflow == (x)) || \
(SwdtFlagRefreshError == (x)))
/*!< SWDT_RR register refresh key */
#define SWDT_REFRESH_START_KEY ((uint16_t)0x0123)
#define SWDT_REFRESH_END_KEY_ ((uint16_t)0x3210)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief SWDT refresh counter
**
** \param [in] None
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t SWDT_RefreshCounter(void)
{
en_result_t enRet = Ok;
M4_SWDT->RR = SWDT_REFRESH_START_KEY;
M4_SWDT->RR = SWDT_REFRESH_END_KEY_;
return enRet;
}
/**
*******************************************************************************
** \brief Get SWDT counter current count value
**
** \param [in] None
**
** \retval uint16_t SWDT counter current count value
**
******************************************************************************/
uint16_t SWDT_GetCountValue(void)
{
return ((uint16_t)M4_SWDT->SR_f.CNT);
}
/**
*******************************************************************************
** \brief Get SWDT flag status
**
** \param [in] enFlag SWDT flag type
** \arg SwdtFlagCountUnderflow Count underflow flag
** \arg SwdtFlagRefreshError Refresh error flag
**
** \retval Set Flag is set
** \retval Reset Flag is reset
**
******************************************************************************/
en_flag_status_t SWDT_GetFlag(en_swdt_flag_type_t enFlag)
{
en_flag_status_t enFlagSta = Reset;
/* Check parameters */
DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
switch (enFlag)
{
case SwdtFlagCountUnderflow:
enFlagSta = (en_flag_status_t)M4_SWDT->SR_f.UDF;
break;
case SwdtFlagRefreshError:
enFlagSta = (en_flag_status_t)M4_SWDT->SR_f.REF;
break;
default:
break;
}
return enFlagSta;
}
/**
*******************************************************************************
** \brief Clear SWDT flag status
**
** \param [in] enFlag SWDT flag type
** \arg SwdtFlagCountUnderflow Count underflow flag
** \arg SwdtFlagRefreshError Refresh error flag
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t SWDT_ClearFlag(en_swdt_flag_type_t enFlag)
{
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
switch (enFlag)
{
case SwdtFlagCountUnderflow:
M4_SWDT->SR_f.UDF = 0u;
break;
case SwdtFlagRefreshError:
M4_SWDT->SR_f.REF = 0u;
break;
default:
break;
}
return enRet;
}
//@} // SwdtGroup
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/

View File

@@ -0,0 +1,963 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_timer0.c
**
** A detailed description is available at
** @link Timer0Group description @endlink
**
** - 2018-10-11 CDT First version for Device Driver Library of TIMER0.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_timer0.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup Timer0Group
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* Parameter validity check for unit. */
#define IS_VALID_UNIT(x) \
( ((x) == M4_TMR01) || \
((x) == M4_TMR02))
/* Parameter validity check for channel. */
#define IS_VALID_CHANNEL(x) \
( ((x) == Tim0_ChannelA) || \
((x) == Tim0_ChannelB))
/* Parameter validity check for command. */
#define IS_VALID_COMMAND(x) \
( ((x) == Disable) || \
((x) == Enable))
/* Parameter validity check for timer0 function mode. */
#define IS_VALID_FUNCTION(x) \
( ((x) == Tim0_OutputCapare) || \
((x) == Tim0_InputCaptrue))
/* Parameter validity check for clock division. */
#define IS_VALID_CLK_DIVISION(x) \
( ((x) == Tim0_ClkDiv0) || \
((x) == Tim0_ClkDiv2) || \
((x) == Tim0_ClkDiv4) || \
((x) == Tim0_ClkDiv8) || \
((x) == Tim0_ClkDiv16) || \
((x) == Tim0_ClkDiv32) || \
((x) == Tim0_ClkDiv64) || \
((x) == Tim0_ClkDiv128) || \
((x) == Tim0_ClkDiv256) || \
((x) == Tim0_ClkDiv512) || \
((x) == Tim0_ClkDiv1024))
/* Parameter validity check for synchronous clock source. */
#define IS_VALID_CLK_SYN_SRC(x) \
( ((x) == Tim0_Pclk1) || \
((x) == Tim0_InsideHardTrig))
/* Parameter validity check for asynchronous clock source. */
#define IS_VALID_CLK_ASYN_SRC(x) \
( ((x) == Tim0_LRC) || \
((x) == Tim0_XTAL32))
/* Parameter validity check for counter clock mode. */
#define IS_VALID_CLK_MODE(x) \
( ((x) == Tim0_Sync) || \
((x) == Tim0_Async))
/* Parameter validity check for counter clock mode for M4_TMR01. */
#define IS_VALID_CLK_MODE_UNIT01(x) \
( (x) == Tim0_Async)
/* Parameter validity check for external trigger event. */
#define IS_VALID_TRIG_SRC_EVENT(x) \
( ((x) <= EVT_PORT_EIRQ15) || \
(((x) >= EVT_DMA1_TC0) && ((x) <= EVT_DMA2_BTC3)) || \
(((x) >= EVT_EFM_OPTEND) && ((x) <= EVT_USBFS_SOF)) || \
(((x) >= EVT_DCU1) && ((x) <= EVT_DCU4)) || \
(((x) >= EVT_TMR01_GCMA) && ((x) <= EVT_TMR02_GCMB)) || \
(((x) >= EVT_RTC_ALM) && ((x) <= EVT_RTC_PRD)) || \
(((x) >= EVT_TMR61_GCMA) && ((x) <= EVT_TMR61_GUDF)) || \
(((x) >= EVT_TMR61_SCMA) && ((x) <= EVT_TMR61_SCMB)) || \
(((x) >= EVT_TMR62_GCMA) && ((x) <= EVT_TMR62_GUDF)) || \
(((x) >= EVT_TMR62_SCMA) && ((x) <= EVT_TMR62_SCMB)) || \
(((x) >= EVT_TMR63_GCMA) && ((x) <= EVT_TMR63_GUDF)) || \
(((x) >= EVT_TMR63_SCMA) && ((x) <= EVT_TMR63_SCMB)) || \
(((x) >= EVT_TMRA1_OVF) && ((x) <= EVT_TMRA5_CMP)) || \
(((x) >= EVT_TMRA6_OVF) && ((x) <= EVT_TMRA6_CMP)) || \
(((x) >= EVT_USART1_EI) && ((x) <= EVT_USART4_RTO)) || \
(((x) >= EVT_SPI1_SPRI) && ((x) <= EVT_AOS_STRG)) || \
(((x) >= EVT_TMR41_SCMUH) && ((x) <= EVT_TMR42_SCMWL)) || \
(((x) >= EVT_TMR43_SCMUH) && ((x) <= EVT_TMR43_SCMWL)) || \
(((x) >= EVT_EVENT_PORT1) && ((x) <= EVT_EVENT_PORT4)) || \
(((x) >= EVT_I2S1_TXIRQOUT) && ((x) <= EVT_I2S1_RXIRQOUT)) || \
(((x) >= EVT_I2S2_TXIRQOUT) && ((x) <= EVT_I2S2_RXIRQOUT)) || \
(((x) >= EVT_I2S3_TXIRQOUT) && ((x) <= EVT_I2S3_RXIRQOUT)) || \
(((x) >= EVT_I2S4_TXIRQOUT) && ((x) <= EVT_I2S4_RXIRQOUT)) || \
(((x) >= EVT_ACMP1) && ((x) <= EVT_ACMP3)) || \
(((x) >= EVT_I2C1_RXI) && ((x) <= EVT_I2C3_EEI)) || \
(((x) >= EVT_PVD_PVD1) && ((x) <= EVT_OTS)) || \
((x) == EVT_WDT_REFUDF) || \
(((x) >= EVT_ADC1_EOCA) && ((x) <= EVT_TRNG_END)) || \
(((x) >= EVT_SDIOC1_DMAR) && ((x) <= EVT_SDIOC1_DMAW)) || \
(((x) >= EVT_SDIOC2_DMAR) && ((x) <= EVT_SDIOC2_DMAW)))
/* Parameter validity check for common trigger. */
#define IS_VALID_TIM0_COM_TRIGGER(x) \
( ((x) == Tim0ComTrigger_1) || \
((x) == Tim0ComTrigger_2) || \
((x) == Tim0ComTrigger_1_2))
/* Delay count for time out */
#define TIMER0_TMOUT (0x5000ul)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Get clock mode
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh channel, Tim0_ChannelA or Tim0_ChannelB
**
** \retval Tim0_Sync: Synchronous clock
** \retval Tim0_Async: Asynchronous clock
**
******************************************************************************/
static en_tim0_counter_mode_t TIMER0_GetClkMode(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh)
{
en_tim0_counter_mode_t enMode = Tim0_Sync;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
switch(enCh)
{
case Tim0_ChannelA:
enMode = (en_tim0_counter_mode_t)pstcTim0Reg->BCONR_f.SYNSA;
break;
case Tim0_ChannelB:
enMode = (en_tim0_counter_mode_t)pstcTim0Reg->BCONR_f.SYNSB;
break;
default:
break;
}
return enMode;
}
/**
*******************************************************************************
** \brief Time delay for register write in asynchronous mode
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Channel, Tim0_ChannelA or Tim0_ChannelB
**
** \param [in] enIsPublicReg Enable for BCONR and STFLR register delay
**
** \retval None
**
******************************************************************************/
static void AsyncDelay(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
en_functional_state_t enIsPublicReg)
{
en_functional_state_t enDelayEn = Disable;
en_tim0_counter_mode_t enModeA = TIMER0_GetClkMode(pstcTim0Reg, Tim0_ChannelA);
en_tim0_counter_mode_t enModeB = TIMER0_GetClkMode(pstcTim0Reg, Tim0_ChannelB);
if(Enable == enIsPublicReg)
{
if((Tim0_Async == enModeA) || (Tim0_Async == enModeB))
{
enDelayEn = Enable;
}
}
else
{
if(Tim0_Async == TIMER0_GetClkMode(pstcTim0Reg, enCh))
{
enDelayEn = Enable;
}
}
if(Enable == enDelayEn)
{
for(uint32_t i=0ul; i<SystemCoreClock/10000ul; i++)
{
__NOP();
}
}
}
/**
*******************************************************************************
** \brief Get Timer0 status flag
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh channel, Tim0_ChannelA or Tim0_ChannelB
**
** \retval Set Flag is set
** Reset Flag is reset
**
******************************************************************************/
en_flag_status_t TIMER0_GetFlag(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh)
{
en_flag_status_t enFlag = Reset;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
switch(enCh)
{
case Tim0_ChannelA:
enFlag = (en_flag_status_t)pstcTim0Reg->STFLR_f.CMAF;
break;
case Tim0_ChannelB:
enFlag = (en_flag_status_t)pstcTim0Reg->STFLR_f.CMBF;
break;
default:
break;
}
return enFlag;
}
/**
*******************************************************************************
** \brief Clear Timer0 status flag
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Timer0_ChA or Timer0_ChB
**
** \retval Ok Success
** \retval ErrorTimeout Process timeout
**
******************************************************************************/
en_result_t TIMER0_ClearFlag(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh)
{
en_result_t enRet = Ok;
uint32_t u32TimeOut = 0ul;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
if(Tim0_ChannelA == enCh)
{
pstcTim0Reg->STFLR_f.CMAF =0u;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(0u != pstcTim0Reg->STFLR_f.CMAF)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
}
else
{
pstcTim0Reg->STFLR_f.CMBF = 0u;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(0u != pstcTim0Reg->STFLR_f.CMBF)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Command the timer0 function
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Timer0_ChA or Timer0_ChB
**
** \param [in] enCmd Disable or Enable the function
**
** \retval Ok Success
** \retval ErrorTimeout Process timeout
**
******************************************************************************/
en_result_t TIMER0_Cmd(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
en_functional_state_t enCmd)
{
en_result_t enRet = Ok;
uint32_t u32TimeOut = 0ul;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
DDL_ASSERT(IS_VALID_COMMAND(enCmd));
switch (enCh)
{
case Tim0_ChannelA:
pstcTim0Reg->BCONR_f.CSTA = enCmd;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(enCmd != pstcTim0Reg->BCONR_f.CSTA)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
break;
case Tim0_ChannelB:
pstcTim0Reg->BCONR_f.CSTB = enCmd;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(enCmd != pstcTim0Reg->BCONR_f.CSTB)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
break;
default:
break;
}
return enRet;
}
/**
*******************************************************************************
** \brief Select the timer0 function mode
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
**
** \param [in] enFunc Timer0 function,Tim0_OutputCapare or Tim0_InputCapture
**
** \retval Ok Success
** \retval ErrorTimeout Process timeout
**
******************************************************************************/
en_result_t TIMER0_SetFunc(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
en_tim0_function_t enFunc)
{
en_result_t enRet = Ok;
uint32_t u32TimeOut = 0ul;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
DDL_ASSERT(IS_VALID_FUNCTION(enFunc));
switch (enCh)
{
case Tim0_ChannelA:
pstcTim0Reg->BCONR_f.CAPMDA = enFunc;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(enFunc != pstcTim0Reg->BCONR_f.CAPMDA)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
break;
case Tim0_ChannelB:
pstcTim0Reg->BCONR_f.CAPMDB = enFunc;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(enFunc != pstcTim0Reg->BCONR_f.CAPMDB)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
break;
default:
break;
}
return enRet;
}
/**
*******************************************************************************
** \brief Timer0 interrupt function command
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
**
** \param [in] enCmd Disable or Enable the function
**
** \retval Ok Success
** \retval ErrorTimeout Process timeout
**
******************************************************************************/
en_result_t TIMER0_IntCmd(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
en_functional_state_t enCmd)
{
en_result_t enRet = Ok;
uint32_t u32TimeOut = 0ul;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
DDL_ASSERT(IS_VALID_COMMAND(enCmd));
switch (enCh)
{
case Tim0_ChannelA:
pstcTim0Reg->BCONR_f.INTENA = enCmd;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(enCmd != pstcTim0Reg->BCONR_f.INTENA)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
break;
case Tim0_ChannelB:
pstcTim0Reg->BCONR_f.INTENB = enCmd;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(enCmd != pstcTim0Reg->BCONR_f.INTENB)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
break;
default:
break;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer0 counter register
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
**
** \retval uint16_t Count register
**
******************************************************************************/
uint16_t TIMER0_GetCntReg(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh)
{
uint16_t u16Value = 0u;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
if(Tim0_ChannelA == enCh)
{
u16Value = (uint16_t)((pstcTim0Reg->CNTAR)&0xFFFFu);
}
else
{
u16Value = (uint16_t)((pstcTim0Reg->CNTBR)&0xFFFFu);
}
return u16Value;
}
/**
*******************************************************************************
** \brief Write Timer0 counter register
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
**
** \param [in] u16Cnt Data to write
**
** \retval Ok Success
** \retval ErrorTimeout Process timeout
**
******************************************************************************/
en_result_t TIMER0_WriteCntReg(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh,
uint16_t u16Cnt)
{
en_result_t enRet = Ok;
uint32_t u32TimeOut = 0ul;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
if(Tim0_ChannelA == enCh)
{
pstcTim0Reg->CNTAR = (uint32_t)u16Cnt;
AsyncDelay(pstcTim0Reg, enCh, Disable);
while(u16Cnt != (uint16_t)pstcTim0Reg->CNTAR)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
}
else
{
pstcTim0Reg->CNTBR = (uint32_t)u16Cnt;
AsyncDelay(pstcTim0Reg, enCh, Disable);
while(u16Cnt != (uint16_t)pstcTim0Reg->CNTBR)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer0 base compare count register
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
**
** \retval uint16_t Base compare count register
**
******************************************************************************/
uint16_t TIMER0_GetCmpReg(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh)
{
uint16_t u16Value = 0u;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
if(Tim0_ChannelA == enCh)
{
u16Value = (uint16_t)((pstcTim0Reg->CMPAR)&0xFFFFu);
}
else
{
u16Value = (uint16_t)((pstcTim0Reg->CMPBR)&0xFFFFu);
}
return u16Value;
}
/**
*******************************************************************************
** \brief Wirte Timer0 base compare count register
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
**
** \param [in] u16Cnt Data to write
**
** \retval Ok Success
** \retval ErrorTimeout Process timeout
**
******************************************************************************/
en_result_t TIMER0_WriteCmpReg(M4_TMR0_TypeDef* pstcTim0Reg, en_tim0_channel_t enCh,
uint16_t u16Cnt)
{
en_result_t enRet = Ok;
uint32_t u32TimeOut = 0ul;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
if(Tim0_ChannelA == enCh)
{
pstcTim0Reg->CMPAR = (uint32_t)u16Cnt;
AsyncDelay(pstcTim0Reg, enCh, Disable);
while(u16Cnt != (uint16_t)pstcTim0Reg->CMPAR)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
}
else
{
pstcTim0Reg->CMPBR = (uint32_t)u16Cnt;
AsyncDelay(pstcTim0Reg, enCh, Disable);
while(u16Cnt != (uint16_t)pstcTim0Reg->CMPBR)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Timer0 peripheral base function initialize
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
**
** \param [in] pstcBaseInit Timer0 function base parameter structure
**
** \retval Ok Process finished.
** \retval ErrorInvalidParameter Parameter error.
** \retval ErrorTimeout Process timeout
**
******************************************************************************/
en_result_t TIMER0_BaseInit(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh,
const stc_tim0_base_init_t* pstcBaseInit)
{
stc_tmr0_bconr_field_t stcBconrTmp;
en_result_t enRet = Ok;
uint32_t u32TimeOut = 0ul;
if (NULL != pstcBaseInit)
{
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
DDL_ASSERT(IS_VALID_CLK_DIVISION(pstcBaseInit->Tim0_ClockDivision));
DDL_ASSERT(IS_VALID_CLK_SYN_SRC(pstcBaseInit->Tim0_SyncClockSource));
DDL_ASSERT(IS_VALID_CLK_ASYN_SRC(pstcBaseInit->Tim0_AsyncClockSource));
DDL_ASSERT(IS_VALID_CLK_MODE(pstcBaseInit->Tim0_CounterMode));
if((M4_TMR01 == pstcTim0Reg)&&(Tim0_ChannelA == enCh))
{
DDL_ASSERT(IS_VALID_CLK_MODE_UNIT01(pstcBaseInit->Tim0_CounterMode));
}
/*Read current BCONR register */
stcBconrTmp = pstcTim0Reg->BCONR_f;
/* Clear current configurate CH */
if(Tim0_ChannelA == enCh)
{
*(uint32_t *)&stcBconrTmp &= 0xFFFF0000ul;
}
else
{
*(uint32_t *)&stcBconrTmp &= 0x0000FFFFul;
}
pstcTim0Reg->BCONR_f = stcBconrTmp;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(*(uint32_t *)&stcBconrTmp != *(uint32_t *)&(pstcTim0Reg->BCONR_f))
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
switch(enCh)
{
case Tim0_ChannelA:
switch(pstcBaseInit->Tim0_CounterMode)
{
case Tim0_Sync:
stcBconrTmp.SYNCLKA = pstcBaseInit->Tim0_SyncClockSource;
break;
case Tim0_Async:
stcBconrTmp.ASYNCLKA = pstcBaseInit->Tim0_AsyncClockSource;
break;
default:
break;
}
/*set clock division*/
stcBconrTmp.CKDIVA = pstcBaseInit->Tim0_ClockDivision;
/* Write BCONR register */
pstcTim0Reg->BCONR_f = stcBconrTmp;
AsyncDelay(pstcTim0Reg, enCh, Enable);
/*set timer compare value*/
pstcTim0Reg->CMPAR = pstcBaseInit->Tim0_CmpValue;
AsyncDelay(pstcTim0Reg, enCh, Enable);
/*set timer counter mode*/
pstcTim0Reg->BCONR_f.SYNSA = pstcBaseInit->Tim0_CounterMode;
AsyncDelay(pstcTim0Reg, enCh, Enable);
u32TimeOut = 0ul;
while(pstcBaseInit->Tim0_CounterMode != pstcTim0Reg->BCONR_f.SYNSA)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
break;
case Tim0_ChannelB:
switch(pstcBaseInit->Tim0_CounterMode)
{
case Tim0_Sync:
stcBconrTmp.SYNCLKB = pstcBaseInit->Tim0_SyncClockSource;
break;
case Tim0_Async:
stcBconrTmp.ASYNCLKB = pstcBaseInit->Tim0_AsyncClockSource;
break;
default:
break;
}
/*set clock division*/
stcBconrTmp.CKDIVB = pstcBaseInit->Tim0_ClockDivision;
/* Write BCONR register */
pstcTim0Reg->BCONR_f = stcBconrTmp;
AsyncDelay(pstcTim0Reg, enCh, Enable);
/*set timer compare value*/
pstcTim0Reg->CMPBR = pstcBaseInit->Tim0_CmpValue;
AsyncDelay(pstcTim0Reg, enCh, Enable);
/*set timer counter mode*/
pstcTim0Reg->BCONR_f.SYNSB = pstcBaseInit->Tim0_CounterMode;
AsyncDelay(pstcTim0Reg, enCh, Enable);
u32TimeOut = 0ul;
while(pstcBaseInit->Tim0_CounterMode != pstcTim0Reg->BCONR_f.SYNSB)
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
break;
default:
break;
}
}
else
{
enRet = ErrorInvalidParameter;
}
return enRet;
}
/**
*******************************************************************************
** \brief Timer0 peripheral base function initalize
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
**
** \retval Ok Process finished.
** \retval ErrorTimeout Process timeout
**
******************************************************************************/
en_result_t TIMER0_DeInit(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh)
{
en_result_t enRet = Ok;
uint32_t u32TimeOut = 0ul;
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
switch(enCh)
{
case Tim0_ChannelA:
pstcTim0Reg->BCONR &= 0xFFFF0000ul;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(0ul != (pstcTim0Reg->BCONR & 0x0000FFFFul))
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
pstcTim0Reg->CMPAR = 0x0000FFFFul;
pstcTim0Reg->CNTAR = 0x00000000ul;
pstcTim0Reg->STFLR_f.CMAF =0u;
break;
case Tim0_ChannelB:
pstcTim0Reg->BCONR &= 0x0000FFFFul;
AsyncDelay(pstcTim0Reg, enCh, Enable);
while(0ul != (pstcTim0Reg->BCONR & 0xFFFF0000ul))
{
if(u32TimeOut++ > TIMER0_TMOUT)
{
enRet = ErrorTimeout;
break;
}
}
pstcTim0Reg->CMPBR = 0x0000FFFFul;
pstcTim0Reg->CNTBR = 0x00000000ul;
pstcTim0Reg->STFLR_f.CMBF =0u;
break;
default:
break;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set external trigger source for Timer0
**
** \param [in] enEvent External event source
**
** \retval None
**
******************************************************************************/
void TIMER0_SetTriggerSrc(en_event_src_t enEvent)
{
DDL_ASSERT(IS_VALID_TRIG_SRC_EVENT(enEvent));
M4_AOS->TMR0_HTSSR_f.TRGSEL = enEvent;
}
/**
*******************************************************************************
** \brief Enable or disable Timer0 common trigger.
**
** \param [in] enComTrigger Timer0 common trigger selection. See @ref en_tim0_com_trigger_t for details.
** \param [in] enState Enable or disable the specified common trigger.
**
** \retval None
**
******************************************************************************/
void TIMER0_ComTriggerCmd(en_tim0_com_trigger_t enComTrigger, en_functional_state_t enState)
{
uint32_t u32ComTrig = (uint32_t)enComTrigger;
DDL_ASSERT(IS_VALID_TIM0_COM_TRIGGER(enComTrigger));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
if (enState == Enable)
{
M4_AOS->TMR0_HTSSR |= (u32ComTrig << 30u);
}
else
{
M4_AOS->TMR0_HTSSR &= ~(u32ComTrig << 30u);
}
}
/**
*******************************************************************************
** \brief Timer0 hardware trigger function initalize
**
** \param [in] pstcTim0Reg Pointer to Timer0 register
**
** \param [in] enCh Timer0 channel, Tim0_ChannelA or Tim0_ChannelB
**
** \param [in] pStcInit Timer0 hareware trigger function structure
**
** \retval Ok Process finished.
** \retval ErrorInvalidParameter Parameter error.
**
******************************************************************************/
en_result_t TIMER0_HardTriggerInit(M4_TMR0_TypeDef* pstcTim0Reg,en_tim0_channel_t enCh,
const stc_tim0_trigger_init_t* pStcInit)
{
stc_tmr0_bconr_field_t stcBconrTmp;
en_result_t enRet = Ok;
if(NULL != pStcInit)
{
DDL_ASSERT(IS_VALID_UNIT(pstcTim0Reg));
DDL_ASSERT(IS_VALID_CHANNEL(enCh));
DDL_ASSERT(IS_VALID_FUNCTION(pStcInit->Tim0_OCMode));
DDL_ASSERT(IS_VALID_TRIG_SRC_EVENT(pStcInit->Tim0_SelTrigSrc));
/*Read current BCONR register */
stcBconrTmp = pstcTim0Reg->BCONR_f;
switch(enCh)
{
case Tim0_ChannelA:
/*set work on input captrue or output capare*/
stcBconrTmp.CAPMDA = pStcInit->Tim0_OCMode;
/*enable input capture*/
stcBconrTmp.HICPA = pStcInit->Tim0_InTrigEnable;
/*enable trigger clear counter*/
stcBconrTmp.HCLEA = pStcInit->Tim0_InTrigClear;
/*enable trigger start counter*/
stcBconrTmp.HSTAA = pStcInit->Tim0_InTrigStart;
/*enable trigger stop counter*/
stcBconrTmp.HSTPA = pStcInit->Tim0_InTrigStop;
/* Write BCONR register */
pstcTim0Reg->BCONR_f = stcBconrTmp;
break;
case Tim0_ChannelB:
/*set work on input captrue or output capare*/
stcBconrTmp.CAPMDB = pStcInit->Tim0_OCMode;
/*enable input capture*/
stcBconrTmp.HICPB = pStcInit->Tim0_InTrigEnable;
/*enable trigger clear counter*/
stcBconrTmp.HCLEB = pStcInit->Tim0_InTrigClear;
/*enable trigger start counter*/
stcBconrTmp.HSTAB = pStcInit->Tim0_InTrigStart;
/*enable trigger stop counter*/
stcBconrTmp.HSTPB = pStcInit->Tim0_InTrigStop;
/* Write BCONR register */
pstcTim0Reg->BCONR_f = stcBconrTmp;
break;
default:
break;
}
AsyncDelay(pstcTim0Reg, enCh, Enable);
/* Set trigger source*/
M4_AOS->TMR0_HTSSR_f.TRGSEL = pStcInit->Tim0_SelTrigSrc;
}
else
{
enRet = ErrorInvalidParameter;
}
return enRet;
}
//@} // Timer0Group
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,838 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_timer4_cnt.c
**
** A detailed description is available at
** @link Timer4CntGroup Timer4CNT description @endlink
**
** - 2018-11-02 CDT First version for Device Driver Library of Timer4CNT.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_timer4_cnt.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup Timer4CntGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter validity check for Timer4 unit */
#define IS_VALID_TIMER4(__TMRx__) \
( (M4_TMR41 == (__TMRx__)) || \
(M4_TMR42 == (__TMRx__)) || \
(M4_TMR43 == (__TMRx__)))
/*!< Parameter validity check for CNT pclk division */
#define IS_VALID_CNT_CLK_DIV(x) \
( (Timer4CntPclkDiv1 == (x)) || \
(Timer4CntPclkDiv2 == (x)) || \
(Timer4CntPclkDiv4 == (x)) || \
(Timer4CntPclkDiv8 == (x)) || \
(Timer4CntPclkDiv16 == (x)) || \
(Timer4CntPclkDiv32 == (x)) || \
(Timer4CntPclkDiv64 == (x)) || \
(Timer4CntPclkDiv128 == (x)) || \
(Timer4CntPclkDiv256 == (x)) || \
(Timer4CntPclkDiv512 == (x)) || \
(Timer4CntPclkDiv1024 == (x)))
/*!< Parameter validity check for CNT mode */
#define IS_VALID_CNT_MODE(x) \
( (Timer4CntSawtoothWave == (x)) || \
(Timer4CntTriangularWave == (x)))
/*!< Parameter validity check for CNT interrupt mask */
#define IS_VALID_CNT_INT_MSK(x) \
( (Timer4CntIntMask0 == (x)) || \
(Timer4CntIntMask1 == (x)) || \
(Timer4CntIntMask2 == (x)) || \
(Timer4CntIntMask3 == (x)) || \
(Timer4CntIntMask4 == (x)) || \
(Timer4CntIntMask5 == (x)) || \
(Timer4CntIntMask6 == (x)) || \
(Timer4CntIntMask7 == (x)) || \
(Timer4CntIntMask8 == (x)) || \
(Timer4CntIntMask9 == (x)) || \
(Timer4CntIntMask10 == (x)) || \
(Timer4CntIntMask11 == (x)) || \
(Timer4CntIntMask12 == (x)) || \
(Timer4CntIntMask13 == (x)) || \
(Timer4CntIntMask14 == (x)) || \
(Timer4CntIntMask15 == (x)))
/*!< Parameter validity check for CNT match interrupt type */
#define IS_VALID_CNT_INT_TYPE(x) \
( (Timer4CntZeroMatchInt == (x)) || \
(Timer4CntPeakMatchInt == (x)))
/*!< Parameter validity check for CNT clock source */
#define IS_VALID_CNT_CLK(x) \
( (Timer4CntPclk == (x)) || \
(Timer4CntExtclk == (x)))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initialize Timer4 CNT
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] pstcInitCfg Pointer to CNT initialization configuration structure
** \arg This parameter detail refer @ref stc_timer4_cnt_init_t
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter If one of following cases matches:
** - TMR4x is invalid
** - pstcInitCfg == NULL
**
******************************************************************************/
en_result_t TIMER4_CNT_Init(M4_TMR4_TypeDef *TMR4x,
const stc_timer4_cnt_init_t *pstcInitCfg)
{
en_result_t enRet = ErrorInvalidParameter;
stc_tmr4_ccsr_field_t CCSR_f = {0};
stc_tmr4_cvpr_field_t CVPR_f = {0};
/* Check for TMR4x && pstcInitCfg pointer */
if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcInitCfg))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_CNT_CLK(pstcInitCfg->enClk));
DDL_ASSERT(IS_VALID_CNT_MODE(pstcInitCfg->enCntMode));
DDL_ASSERT(IS_VALID_CNT_CLK_DIV(pstcInitCfg->enClkDiv));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enBufferCmd));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enZeroIntCmd));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enPeakIntCmd));
DDL_ASSERT(IS_VALID_CNT_INT_MSK(pstcInitCfg->enZeroIntMsk));
DDL_ASSERT(IS_VALID_CNT_INT_MSK(pstcInitCfg->enPeakIntMsk));
/* Set default value */
TMR4x->CCSR = (uint16_t)0x0050u;
TMR4x->CNTR = (uint16_t)0x0000u;
TMR4x->CPSR = (uint16_t)0xFFFFu;
TMR4x->CVPR = (uint16_t)0x0000u;
/* stop count of CNT */
CCSR_f.STOP = 1u;
/* set count clock div of CNT */
CCSR_f.CKDIV = pstcInitCfg->enClkDiv;
/* set cnt mode */
CCSR_f.MODE = pstcInitCfg->enCntMode;
/* set buffer enable bit */
CCSR_f.BUFEN = (uint16_t)(pstcInitCfg->enBufferCmd);
/* set external clock enable bit */
CCSR_f.ECKEN = (Timer4CntExtclk == pstcInitCfg->enClk) ? ((uint16_t)1u) : ((uint16_t)0u);
/* Set interrupt enable */
CCSR_f.IRQZEN = (uint16_t)(pstcInitCfg->enZeroIntCmd);
CCSR_f.IRQPEN = (uint16_t)(pstcInitCfg->enPeakIntCmd);
/* set intterrupt mask times */
CVPR_f.ZIM = (uint16_t)(pstcInitCfg->enZeroIntMsk);
CVPR_f.PIM = (uint16_t)(pstcInitCfg->enPeakIntMsk);
/* Set Timer4 register */
TMR4x->CVPR = *(uint16_t *)(&CVPR_f);
TMR4x->CCSR_f = CCSR_f;
TMR4x->CPSR = pstcInitCfg->u16Cycle;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief De-initialize Timer4 CNT
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval Ok De-Initialize successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_DeInit(M4_TMR4_TypeDef *TMR4x)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Set default value */
TMR4x->CCSR = (uint16_t)0x0050u;
TMR4x->CNTR = (uint16_t)0x0000u;
TMR4x->CPSR = (uint16_t)0xFFFFu;
TMR4x->CVPR = (uint16_t)0x0000u;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set Timer4 CNT clock source
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCntClk Timer4 CNT clock source
** \arg Timer4CntPclk Uses the internal clock (PCLK) as CNT's count clock.
** \arg Timer4CntExtclk Uses an external input clock (EXCK) as CNT's count clock.
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_SetClock(M4_TMR4_TypeDef *TMR4x,
en_timer4_cnt_clk_t enCntClk)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_CNT_CLK(enCntClk));
/* set external clock enable bit */
TMR4x->CCSR_f.ECKEN = (uint16_t)(enCntClk);
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer4 CNT clock source
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval Timer4CntPclk Uses the internal clock (PCLK) as CNT's count clock.
** \retval Timer4CntExtclk Uses an external input clock (EXCK) as CNT's count clock.
**
******************************************************************************/
en_timer4_cnt_clk_t TIMER4_CNT_GetClock(M4_TMR4_TypeDef *TMR4x)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
return (en_timer4_cnt_clk_t)(TMR4x->CCSR_f.ECKEN);
}
/**
*******************************************************************************
** \brief Set Timer4 CNT clock division
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enClkDiv Timer4 CNT clock division
** \arg Timer4CntPclkDiv1 Timer4 CNT clock: PCLK
** \arg Timer4CntPclkDiv2 Timer4 CNT clock: PCLK/2
** \arg Timer4CntPclkDiv4 Timer4 CNT clock: PCLK/4
** \arg Timer4CntPclkDiv8 Timer4 CNT clock: PCLK/8
** \arg Timer4CntPclkDiv16 Timer4 CNT clock: PCLK/16
** \arg Timer4CntPclkDiv32 Timer4 CNT clock: PCLK/32
** \arg Timer4CntPclkDiv64 Timer4 CNT clock: PCLK/64
** \arg Timer4CntPclkDiv128 Timer4 CNT clock: PCLK/128
** \arg Timer4CntPclkDiv256 Timer4 CNT clock: PCLK/256
** \arg Timer4CntPclkDiv512 Timer4 CNT clock: PCLK/512
** \arg Timer4CntPclkDiv1024 Timer4 CNT clock: PCLK/1024
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_SetClockDiv(M4_TMR4_TypeDef *TMR4x,
en_timer4_cnt_clk_div_t enClkDiv)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_CNT_CLK_DIV(enClkDiv));
TMR4x->CCSR_f.CKDIV = (uint16_t)enClkDiv;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer4 CNT clock division
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval Timer4CntPclkDiv1 Timer4 CNT clock: PCLK
** \retval Timer4CntPclkDiv2 Timer4 CNT clock: PCLK/2
** \retval Timer4CntPclkDiv4 Timer4 CNT clock: PCLK/4
** \retval Timer4CntPclkDiv8 Timer4 CNT clock: PCLK/8
** \retval Timer4CntPclkDiv16 Timer4 CNT clock: PCLK/16
** \retval Timer4CntPclkDiv32 Timer4 CNT clock: PCLK/32
** \retval Timer4CntPclkDiv64 Timer4 CNT clock: PCLK/64
** \retval Timer4CntPclkDiv128 Timer4 CNT clock: PCLK/128
** \retval Timer4CntPclkDiv256 Timer4 CNT clock: PCLK/256
** \retval Timer4CntPclkDiv512 Timer4 CNT clock: PCLK/512
** \retval Timer4CntPclkDiv1024 Timer4 CNT clock: PCLK/1024
**
******************************************************************************/
en_timer4_cnt_clk_div_t TIMER4_CNT_GetClockDiv(M4_TMR4_TypeDef *TMR4x)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
return (en_timer4_cnt_clk_div_t)(TMR4x->CCSR_f.CKDIV);
}
/**
*******************************************************************************
** \brief Set Timer4 CNT mode
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enMode Timer4 CNT mode
** \arg Timer4CntSawtoothWave Timer4 count mode:sawtooth wave
** \arg Timer4CntTriangularWave Timer4 count mode:triangular wave
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_SetMode(M4_TMR4_TypeDef *TMR4x,
en_timer4_cnt_mode_t enMode)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_CNT_MODE(enMode));
TMR4x->CCSR_f.MODE = (uint16_t)enMode;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer4 CNT mode
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval Timer4CntSawtoothWave Timer4 count mode:sawtooth wave
** \retval Timer4CntTriangularWave Timer4 count mode:triangular wave
**
******************************************************************************/
en_timer4_cnt_mode_t TIMER4_CNT_GetMode(M4_TMR4_TypeDef *TMR4x)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
return (en_timer4_cnt_mode_t)(TMR4x->CCSR_f.MODE);
}
/**
*******************************************************************************
** \brief Start Timer4 CNT
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval Ok Start successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_Start(M4_TMR4_TypeDef *TMR4x)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
TMR4x->CCSR_f.STOP = (uint16_t)0u;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Stop Timer4 CNT
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval Ok Stop successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_Stop(M4_TMR4_TypeDef *TMR4x)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
TMR4x->CCSR_f.STOP = (uint16_t)1u;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set Timer4 CNT interrupt
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enIntType The specified type of Timer4 CNT interrupt
** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
** \param [in] enCmd DCU interrupt functional state
** \arg Enable Enable the specified Timer4 CNT interrupt function
** \arg Disable Disable the specified Timer4 CNT interrupt function
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter If one of following cases matches:
** - TMR4x is invalid
** - enIntType is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_IrqCmd(M4_TMR4_TypeDef *TMR4x,
en_timer4_cnt_int_t enIntType,
en_functional_state_t enCmd)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
enRet = Ok;
switch (enIntType)
{
case Timer4CntZeroMatchInt:
TMR4x->CCSR_f.IRQZEN = (uint16_t)enCmd;
break;
case Timer4CntPeakMatchInt:
TMR4x->CCSR_f.IRQPEN = (uint16_t)enCmd;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer4 CNT interrupt flag
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enIntType Timer4 CNT interrupt type
** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
**
** \retval Reset None interrupt request on Timer4 CNT
** \retval Set Detection interrupt request on Timer4 CNT
**
******************************************************************************/
en_flag_status_t TIMER4_CNT_GetIrqFlag(M4_TMR4_TypeDef *TMR4x,
en_timer4_cnt_int_t enIntType)
{
uint16_t u16Flag = 0u;
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
switch (enIntType)
{
case Timer4CntZeroMatchInt:
u16Flag = TMR4x->CCSR_f.IRQZF;
break;
case Timer4CntPeakMatchInt:
u16Flag = TMR4x->CCSR_f.IRQPF;
break;
default:
break;
}
return (en_flag_status_t)u16Flag;
}
/**
*******************************************************************************
** \brief Clear Timer4 CNT interrupt flag
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enIntType Timer4 CNT interrupt type
** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
**
** \retval Ok Clear successfully.
** \retval ErrorInvalidParameter If one of following cases matches:
** - TMR4x is invalid
** - enIntType is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_ClearIrqFlag(M4_TMR4_TypeDef *TMR4x,
en_timer4_cnt_int_t enIntType)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
enRet = Ok;
switch (enIntType)
{
case Timer4CntZeroMatchInt:
TMR4x->CCSR_f.IRQZF = (uint16_t)0u;
break;
case Timer4CntPeakMatchInt:
TMR4x->CCSR_f.IRQPF = (uint16_t)0u;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Set the cycle value of the specified Timer4 CNT.
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] u16Cycle The Timer4 CNT cycle value
** \arg number of 16bit
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_SetCycleVal(M4_TMR4_TypeDef *TMR4x, uint16_t u16Cycle)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
TMR4x->CPSR = u16Cycle;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get the cycle value of the specified Timer4 CNT.
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval The cycle value of the specified Timer4 CNT.
**
******************************************************************************/
uint16_t TIMER4_CNT_GetCycleVal(const M4_TMR4_TypeDef *TMR4x)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
return TMR4x->CPSR;
}
/**
*******************************************************************************
** \brief Clear Timer4 CNT register CNTR
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval Ok Clear successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_ClearCountVal(M4_TMR4_TypeDef *TMR4x)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
TMR4x->CCSR_f.CLEAR = (uint16_t)1u;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set the current count value of the specified Timer4 CNT.
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] u16Count The Timer4 CNT current count value
** \arg number of 16bit
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_SetCountVal(M4_TMR4_TypeDef *TMR4x, uint16_t u16Count)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
TMR4x->CNTR = u16Count;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer4 CNT current count value
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval The current count value of the specified Timer4 CNT.
**
******************************************************************************/
uint16_t TIMER4_CNT_GetCountVal(const M4_TMR4_TypeDef *TMR4x)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
return TMR4x->CNTR;
}
/**
*******************************************************************************
** \brief Set Timer4 CNT interrupt mask times
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enIntType Timer4 CNT interrupt type
** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
** \param [in] enMaskTimes Timer4 CNT interrupt mask times
** \arg Timer4CntIntMask0 CNT interrupt flag is always set(not masked) for every CNT count at "0x0000" or peak.
** \arg Timer4CntIntMask1 CNT interrupt flag is set once for 2 every CNT counts at "0x0000" or peak (skiping 1 count).
** \arg Timer4CntIntMask2 CNT interrupt flag is set once for 3 every CNT counts at "0x0000" or peak (skiping 2 count).
** \arg Timer4CntIntMask3 CNT interrupt flag is set once for 4 every CNT counts at "0x0000" or peak (skiping 3 count).
** \arg Timer4CntIntMask4 CNT interrupt flag is set once for 5 every CNT counts at "0x0000" or peak (skiping 4 count).
** \arg Timer4CntIntMask5 CNT interrupt flag is set once for 6 every CNT counts at "0x0000" or peak (skiping 5 count).
** \arg Timer4CntIntMask6 CNT interrupt flag is set once for 7 every CNT counts at "0x0000" or peak (skiping 6 count).
** \arg Timer4CntIntMask7 CNT interrupt flag is set once for 8 every CNT counts at "0x0000" or peak (skiping 7 count).
** \arg Timer4CntIntMask8 CNT interrupt flag is set once for 9 every CNT counts at "0x0000" or peak (skiping 8 count).
** \arg Timer4CntIntMask9 CNT interrupt flag is set once for 10 every CNT counts at "0x0000" or peak (skiping 9 count).
** \arg Timer4CntIntMask10 CNT interrupt flag is set once for 11 every CNT counts at "0x0000" or peak (skiping 10 count).
** \arg Timer4CntIntMask11 CNT interrupt flag is set once for 12 every CNT counts at "0x0000" or peak (skiping 11 count).
** \arg Timer4CntIntMask12 CNT interrupt flag is set once for 13 every CNT counts at "0x0000" or peak (skiping 12 count).
** \arg Timer4CntIntMask13 CNT interrupt flag is set once for 14 every CNT counts at "0x0000" or peak (skiping 13 count).
** \arg Timer4CntIntMask14 CNT interrupt flag is set once for 15 every CNT counts at "0x0000" or peak (skiping 14 count).
** \arg Timer4CntIntMask15 CNT interrupt flag is set once for 16 every CNT counts at "0x0000" or peak (skiping 15 count).
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_CNT_SetIntMaskTimes(M4_TMR4_TypeDef *TMR4x,
en_timer4_cnt_int_t enIntType,
en_timer4_cnt_int_mask_t enMaskTimes)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
DDL_ASSERT(IS_VALID_CNT_INT_MSK(enMaskTimes));
enRet = Ok;
switch (enIntType)
{
case Timer4CntZeroMatchInt:
TMR4x->CVPR_f.ZIM = (uint16_t)enMaskTimes;
break;
case Timer4CntPeakMatchInt:
TMR4x->CVPR_f.PIM = (uint16_t)enMaskTimes;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer4 CNT interrupt mask times
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enIntType Timer4 CNT interrupt type
** \arg Timer4CntZeroMatchIrq Zero match interrupt of Timer4 CNT
** \arg Timer4CntPeakMatchIrq Peak match interrupt of Timer4 CNT
**
** \retval Timer4CntIntMask0 CNT interrupt flag is always set(not masked) for every CNT count at "0x0000" or peak.
** \retval Timer4CntIntMask1 CNT interrupt flag is set once for 2 every CNT counts at "0x0000" or peak (skiping 1 count).
** \retval Timer4CntIntMask2 CNT interrupt flag is set once for 3 every CNT counts at "0x0000" or peak (skiping 2 count).
** \retval Timer4CntIntMask3 CNT interrupt flag is set once for 4 every CNT counts at "0x0000" or peak (skiping 3 count).
** \retval Timer4CntIntMask4 CNT interrupt flag is set once for 5 every CNT counts at "0x0000" or peak (skiping 4 count).
** \retval Timer4CntIntMask5 CNT interrupt flag is set once for 6 every CNT counts at "0x0000" or peak (skiping 5 count).
** \retval Timer4CntIntMask6 CNT interrupt flag is set once for 7 every CNT counts at "0x0000" or peak (skiping 6 count).
** \retval Timer4CntIntMask7 CNT interrupt flag is set once for 8 every CNT counts at "0x0000" or peak (skiping 7 count).
** \retval Timer4CntIntMask8 CNT interrupt flag is set once for 9 every CNT counts at "0x0000" or peak (skiping 8 count).
** \retval Timer4CntIntMask9 CNT interrupt flag is set once for 10 every CNT counts at "0x0000" or peak (skiping 9 count).
** \retval Timer4CntIntMask10 CNT interrupt flag is set once for 11 every CNT counts at "0x0000" or peak (skiping 10 count).
** \retval Timer4CntIntMask11 CNT interrupt flag is set once for 12 every CNT counts at "0x0000" or peak (skiping 11 count).
** \retval Timer4CntIntMask12 CNT interrupt flag is set once for 13 every CNT counts at "0x0000" or peak (skiping 12 count).
** \retval Timer4CntIntMask13 CNT interrupt flag is set once for 14 every CNT counts at "0x0000" or peak (skiping 13 count).
** \retval Timer4CntIntMask14 CNT interrupt flag is set once for 15 every CNT counts at "0x0000" or peak (skiping 14 count).
** \retval Timer4CntIntMask15 CNT interrupt flag is set once for 16 every CNT counts at "0x0000" or peak (skiping 15 count).
**
******************************************************************************/
en_timer4_cnt_int_mask_t TIMER4_CNT_GetIntMaskTimes(M4_TMR4_TypeDef *TMR4x,
en_timer4_cnt_int_t enIntType)
{
uint16_t u16MaskTimes = 0u;
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
DDL_ASSERT(IS_VALID_CNT_INT_TYPE(enIntType));
switch (enIntType)
{
case Timer4CntZeroMatchInt:
u16MaskTimes = TMR4x->CVPR_f.ZIM;
break;
case Timer4CntPeakMatchInt:
u16MaskTimes = TMR4x->CVPR_f.PIM;
break;
default:
break;
}
return (en_timer4_cnt_int_mask_t)u16MaskTimes;
}
//@} // Timer4CntGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,274 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_timer4_emb.c
**
** A detailed description is available at
** @link Timer4EmbGroup Timer4EMB description @endlink
**
** - 2018-11-02 CDT First version for Device Driver Library of Timer4EMB.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_timer4_emb.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup Timer4EmbGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter validity check for Timer4 unit */
#define IS_VALID_TIMER4(__TMRx__) \
( (M4_TMR41 == (__TMRx__)) || \
(M4_TMR42 == (__TMRx__)) || \
(M4_TMR43 == (__TMRx__)))
/*!< Parameter valid check for EMB HOLD mode. */
#define IS_VALID_EMB_HOLD_MODE(x) \
( (EmbHoldPwm == (x)) || \
(EmbChangePwm == (x)))
/*!< Parameter valid check for EMB state. */
#define IS_VALID_EMB_STATE(x) \
( (EmbTrigPwmOutputHiz == (x)) || \
(EmbTrigPwmOutputNormal == (x)) || \
(EmbTrigPwmOutputLowLevel == (x)) || \
(EmbTrigPwmOutputHighLevel == (x)))
/*!< Timer4x ECER register address. */
#define TMR4_ECERx(__TMRx__) \
( (M4_TMR41 == (__TMRx__)) ? &M4_TMR4_CR->ECER1 : \
((M4_TMR42 == (__TMRx__)) ? &M4_TMR4_CR->ECER2 : &M4_TMR4_CR->ECER3))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initialize Timer4 EMB
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] pstcInitCfg The pointer of EMB configure structure
** \arg This parameter detail refer @ref stc_timer4_emb_init_t
**
** \retval Ok Initialize successfully
** \retval ErrorInvalidParameter If one of following conditions are met:
** - TMR4x is invalid
** - pstcInitCfg == NULL
**
******************************************************************************/
en_result_t TIMER4_EMB_Init(M4_TMR4_TypeDef *TMR4x,
const stc_timer4_emb_init_t *pstcInitCfg)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x && pstcInitCfg pointer */
if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcInitCfg))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_EMB_STATE(pstcInitCfg->enEmbState));
DDL_ASSERT(IS_VALID_EMB_HOLD_MODE(pstcInitCfg->enPwmHold));
/* Set EMB HOLD mode */
TMR4x->ECSR_f.HOLD = (uint16_t)(pstcInitCfg->enPwmHold);
/* Set EMB state */
*(__IO uint32_t *)TMR4_ECERx(TMR4x) = (uint32_t)(pstcInitCfg->enEmbState);
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief De-initialize Timer4 EMB
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval Ok De-Initialize successfully
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_EMB_DeInit(M4_TMR4_TypeDef *TMR4x)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Set reset value(0x0000) to register ESCR */
TMR4x->ECSR = 0u;
/* Set reset value(0x0000) to register ECER */
*(__IO uint32_t *)TMR4_ECERx(TMR4x) = (uint32_t)0ul;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set Timer4 EMB HOLD mode
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enHoldMode EMB HOLD mode
** \arg EmbChangePwm Don't hold PWM output when EMB signal occurs
** \arg EmbHoldPwm Hold PWM output when EMB signal occurs
**
** \retval Ok Set successfully
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_EMB_SetHoldMode(M4_TMR4_TypeDef *TMR4x,
en_timer4_emb_hold_mode_t enHoldMode)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_EMB_HOLD_MODE(enHoldMode));
/* Set EMB HOLD mode */
TMR4x->ECSR_f.HOLD = (uint16_t)enHoldMode;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer4 EMB HOLD mode
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval EmbChangePwm Don't hold PWM output when EMB signal occurs
** \retval EmbHoldPwm Hold PWM output when EMB signal occurs
**
******************************************************************************/
en_timer4_emb_hold_mode_t TIMER4_EMB_GetHoldMode(M4_TMR4_TypeDef *TMR4x)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
return (en_timer4_emb_hold_mode_t)(TMR4x->ECSR_f.HOLD);
}
/**
*******************************************************************************
** \brief Set Timer4 EMB state
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enEmbState EMB state
** \arg EmbTrigPwmOutputNormal PWM output signal normally.
** \arg EmbTrigPwmOutputHiz PWM output Hiz signal.
** \arg EmbTrigPwmOutputLowLevel PWM output low level signal.
** \arg EmbTrigPwmOutputHighLevel PWM output high level signal.
**
** \retval Ok Set successfully
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_EMB_SetState(const M4_TMR4_TypeDef *TMR4x,
en_timer4_emb_state_t enEmbState)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_EMB_STATE(enEmbState));
/* Set EMB state */
*(__IO uint32_t *)TMR4_ECERx(TMR4x) = (uint32_t)enEmbState;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer4 EMB state
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
**
** \retval EmbTrigPwmOutputNormal PWM output signal normally.
** \retval EmbTrigPwmOutputHiz PWM output Hiz signal.
** \retval EmbTrigPwmOutputLowLevel PWM output low level signal.
** \retval EmbTrigPwmOutputHighLevel PWM output high level signal.
**
******************************************************************************/
en_timer4_emb_state_t TIMER4_EMB_GetState(const M4_TMR4_TypeDef *TMR4x)
{
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
return *(__IO en_timer4_emb_state_t *)TMR4_ECERx(TMR4x);
}
//@} // Timer4EmbGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,596 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_timer4_pwm.c
**
** A detailed description is available at
** @link Timer4PwmGroup Timer4PWM description @endlink
**
** - 2018-11-02 CDT First version for Device Driver Library of Timer4PWM.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_timer4_pwm.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup Timer4PwmGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter validity check for Timer4 unit */
#define IS_VALID_TIMER4(__TMRx__) \
( (M4_TMR41 == (__TMRx__)) || \
(M4_TMR42 == (__TMRx__)) || \
(M4_TMR43 == (__TMRx__)))
/*!< Parameter validity check for PWM channel */
#define IS_VALID_PWM_CH(x) \
( (Timer4PwmU == (x)) || \
(Timer4PwmV == (x)) || \
(Timer4PwmW == (x)))
/*!< Parameter validity check for PWM mode */
#define IS_VALID_PWM_MODE(x) \
( (PwmThroughMode == (x)) || \
(PwmDeadTimerMode == (x)) || \
(PwmDeadTimerFilterMode == (x)))
/*!< Parameter valid check for PWM output state. */
#define IS_VALID_PWM_OUTPUT_STATE(x) \
( (PwmHPwmLHold == (x)) || \
(PwmHPwmLReverse == (x)) || \
(PwmHReversePwmLHold == (x)) || \
(PwmHHoldPwmLReverse == (x)))
/*!< Parameter valid check for PWM clock division. */
#define IS_VALID_PWM_CLK_DIV(x) \
( (PwmPlckDiv1 == (x)) || \
(PwmPlckDiv2 == (x)) || \
(PwmPlckDiv4 == (x)) || \
(PwmPlckDiv8 == (x)) || \
(PwmPlckDiv16 == (x)) || \
(PwmPlckDiv32 == (x)) || \
(PwmPlckDiv64 == (x)) || \
(PwmPlckDiv128 == (x)))
/*!< Get the specified register address of the specified Timer4 unit */
#define TMR4_RCSRx(__TMR4x__) ((uint32_t)&(__TMR4x__)->RCSR)
#define TMR4_POCRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->POCRU + ((uint32_t)(__CH__))*4ul)
#define TMR4_PDARx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->PDARU + ((uint32_t)(__CH__))*8ul)
#define TMR4_PDBRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->PDBRU + ((uint32_t)(__CH__))*8ul)
#define TMR4_PFSRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->PFSRU + ((uint32_t)(__CH__))*8ul)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initialize a couple PWM channels
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Channel of PWM
** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
** \param [in] pstcInitCfg The pointer of PWM configure structure
** \arg This parameter detail refer @ref stc_timer4_pwm_init_t
**
** \retval Ok Initialize successfully
** \retval ErrorInvalidParameter If one of following conditions are met:
** - TMR4x is invalid
** - pstcInitCfg == NULL
** - enCh is invalid
** - Other invalid configuration
**
******************************************************************************/
en_result_t TIMER4_PWM_Init(M4_TMR4_TypeDef *TMR4x,
en_timer4_pwm_ch_t enCh,
const stc_timer4_pwm_init_t *pstcInitCfg)
{
__IO stc_tmr4_pocr_field_t *pstcPOCR_f = NULL;
__IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
en_result_t enRet = Ok;
/* Check TMR4x && pstcInitCfg pointer */
if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcInitCfg))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_PWM_MODE(pstcInitCfg->enMode));
DDL_ASSERT(IS_VALID_PWM_CLK_DIV(pstcInitCfg->enClkDiv));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enRtIntMaskCmd));
DDL_ASSERT(IS_VALID_PWM_OUTPUT_STATE(pstcInitCfg->enOutputState));
/* Get pointer of current channel PWM register address */
pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
pstcPOCR_f = (__IO stc_tmr4_pocr_field_t*)TMR4_POCRx(TMR4x, enCh);
/* Configure PWM mode */
pstcPOCR_f->PWMMD = (uint16_t)(pstcInitCfg->enMode);
/* Configure PWM mode */
pstcPOCR_f->LVLS = (uint16_t)(pstcInitCfg->enOutputState);
/* Set timer clock division */
pstcPOCR_f->DIVCK = (uint16_t)(pstcInitCfg->enClkDiv);
/* Set interrupt mask */
switch (enCh)
{
case Timer4PwmU:
pstcRCSR_f->RTIDU = (uint16_t)(pstcInitCfg->enRtIntMaskCmd);
break;
case Timer4PwmV:
pstcRCSR_f->RTIDV = (uint16_t)(pstcInitCfg->enRtIntMaskCmd);
break;
case Timer4PwmW:
pstcRCSR_f->RTIDW = (uint16_t)(pstcInitCfg->enRtIntMaskCmd);
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
else
{
enRet = ErrorInvalidParameter;
}
return enRet;
}
/**
*******************************************************************************
** \brief De-Initialize a couple PWM channels
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Channel of PWM
** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
**
** \retval Ok De-Initialize successfully.
** \retval ErrorInvalidParameter If one of following conditions are met:
** - TMR4x is invalid
** - enCh out of range
**
******************************************************************************/
en_result_t TIMER4_PWM_DeInit(M4_TMR4_TypeDef *TMR4x,
en_timer4_pwm_ch_t enCh)
{
en_result_t enRet = Ok;
__IO uint16_t *pu16PDAR = NULL;
__IO uint16_t *pu16PDBR = NULL;
__IO uint16_t *pu16PFSR = NULL;
__IO stc_tmr4_pocr_field_t *pstcPOCR_f = NULL;
__IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Get pointer of current channel PWM register address */
pu16PDAR = (__IO uint16_t*)TMR4_PDARx(TMR4x, enCh);
pu16PDBR = (__IO uint16_t*)TMR4_PDBRx(TMR4x, enCh);
pu16PFSR = (__IO uint16_t*)TMR4_PFSRx(TMR4x, enCh);
pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
pstcPOCR_f = (__IO stc_tmr4_pocr_field_t*)TMR4_POCRx(TMR4x, enCh);
*pu16PDAR = (uint16_t)0u;
*pu16PDBR = (uint16_t)0u;
*pu16PFSR = (uint16_t)0u;
pstcPOCR_f->DIVCK = (uint16_t)0u;
pstcPOCR_f->LVLS = (uint16_t)0u;
pstcPOCR_f->PWMMD = (uint16_t)0u;
switch (enCh)
{
case Timer4PwmU:
pstcRCSR_f->RTIDU = (uint16_t)0u;
break;
case Timer4PwmV:
pstcRCSR_f->RTIDV = (uint16_t)0u;
break;
case Timer4PwmW:
pstcRCSR_f->RTIDW = (uint16_t)0u;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
else
{
enRet = ErrorInvalidParameter;
}
return enRet;
}
/**
*******************************************************************************
** \brief Start PWM timer
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Channel of PWM
** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
**
** \retval Ok Start timer successfully
** \retval ErrorInvalidParameter If one of following conditions are met:
** - TMR4x is invalid
** - enCh out of range
**
******************************************************************************/
en_result_t TIMER4_PWM_StartTimer(M4_TMR4_TypeDef *TMR4x,
en_timer4_pwm_ch_t enCh)
{
en_result_t enRet = ErrorInvalidParameter;
__IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
enRet = Ok;
/* Get pointer of current channel PWM register address */
pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
switch (enCh)
{
case Timer4PwmU:
pstcRCSR_f->RTEU = (uint16_t)1u;
break;
case Timer4PwmV:
pstcRCSR_f->RTEV = (uint16_t)1u;
break;
case Timer4PwmW:
pstcRCSR_f->RTEW = (uint16_t)1u;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Stop PWM timer
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Channel of PWM
** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
**
** \retval Ok Stop timer successfully
** \retval ErrorInvalidParameter If one of following conditions are met:
** - TMR4x is invalid
** - enCh out of range
**
******************************************************************************/
en_result_t TIMER4_PWM_StopTimer(M4_TMR4_TypeDef *TMR4x,
en_timer4_pwm_ch_t enCh)
{
en_result_t enRet = ErrorInvalidParameter;
__IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
/* Check parameters */
DDL_ASSERT(IS_VALID_PWM_CH(enCh));
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
enRet = Ok;
/* Get pointer of current channel PWM register address */
pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
switch (enCh)
{
case Timer4PwmU:
pstcRCSR_f->RTSU = (uint16_t)1u;
break;
case Timer4PwmV:
pstcRCSR_f->RTSV = (uint16_t)1u;
break;
case Timer4PwmW:
pstcRCSR_f->RTSW = (uint16_t)1u;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Get PWM reload-timer interrupt flag
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Channel of PWM
** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
**
** \retval Reset None interrupt request on PWM reload-timer
** \retval Set Detection interrupt request on PWM reload-timer
**
******************************************************************************/
en_flag_status_t TIMER4_PWM_GetIrqFlag(M4_TMR4_TypeDef *TMR4x,
en_timer4_pwm_ch_t enCh)
{
uint16_t u16Flag = 0u;
__IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
/* Check parameters */
DDL_ASSERT(IS_VALID_PWM_CH(enCh));
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
/* Get pointer of current channel PWM register address */
pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
switch (enCh)
{
case Timer4PwmU:
u16Flag = pstcRCSR_f->RTIFU;
break;
case Timer4PwmV:
u16Flag = pstcRCSR_f->RTIFV;
break;
case Timer4PwmW:
u16Flag = pstcRCSR_f->RTIFW;
break;
default:
break;
}
return (en_flag_status_t)u16Flag;
}
/**
*******************************************************************************
** \brief Clear PWM reload-timer interrupt flag
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Channel of PWM
** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
**
** \retval Ok PWM reload-timer interrupt flag is clear
** \retval ErrorInvalidParameter If one of following conditions are met:
** - TMR4x is invalid
** - enCh out of range
**
******************************************************************************/
en_result_t TIMER4_PWM_ClearIrqFlag(M4_TMR4_TypeDef *TMR4x,
en_timer4_pwm_ch_t enCh)
{
en_result_t enRet = ErrorInvalidParameter;
__IO stc_tmr4_rcsr_field_t *pstcRCSR_f = NULL;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_PWM_CH(enCh));
enRet = Ok;
/* Get pointer of current channel PWM register address */
pstcRCSR_f = (__IO stc_tmr4_rcsr_field_t*)TMR4_RCSRx(TMR4x);
switch (enCh)
{
case Timer4PwmU:
pstcRCSR_f->RTICU = (uint16_t)1u;
break;
case Timer4PwmV:
pstcRCSR_f->RTICV = (uint16_t)1u;
break;
case Timer4PwmW:
pstcRCSR_f->RTICW = (uint16_t)1u;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Write timer count cycle
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Channel of PWM
** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
** \param [in] u16PDAR PDAR value
** \arg 0~65535
** \param [in] u16PDBR PDBR value
** \arg 0~65535
**
** \retval Ok Timer count cycle is written
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_PWM_WriteDeadRegionValue(M4_TMR4_TypeDef *TMR4x,
en_timer4_pwm_ch_t enCh,
uint16_t u16PDAR,
uint16_t u16PDBR)
{
__IO uint16_t *pu16PDAR = NULL;
__IO uint16_t *pu16PDBR = NULL;
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_PWM_CH(enCh));
/* Get pointer of current channel PWM register address */
pu16PDAR = (__IO uint16_t *)TMR4_PDARx(TMR4x, enCh);
pu16PDBR = (__IO uint16_t *)TMR4_PDBRx(TMR4x, enCh);
/* set the register */
*pu16PDAR = u16PDAR;
*pu16PDBR = u16PDBR;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Read dead region count value
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Channel of PWM
** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
** \param [out] u16PDAR Pointer of uint16_t type
** \arg 0~65535
** \param [out] u16PDBR Pointer of uint16_t type
** \arg 0~65535
**
** \retval Ok Read successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_PWM_ReadDeadRegionValue(M4_TMR4_TypeDef *TMR4x,
en_timer4_pwm_ch_t enCh,
uint16_t *u16PDAR,
uint16_t *u16PDBR)
{
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_PWM_CH(enCh));
/* Get pointer of current channel PWM register address */
*u16PDAR = *(__IO uint16_t *)TMR4_PDARx(TMR4x, enCh);
*u16PDBR = *(__IO uint16_t *)TMR4_PDBRx(TMR4x, enCh);
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set cycle of PWM timer
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Channel of PWM
** \arg Timer4PwmOuhl Timer4 PWM couple channel OUH&OUL
** \arg Timer4PwmOvhl Timer4 PWM couple channel OVH&OVL
** \arg Timer4PwmOwhl Timer4 PWM couple channel OWH&OWL
** \param [in] u16Count PWM pulse counter value
** \arg 0~65535
**
** \retval Ok Cycle of PWM timer is set
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_PWM_SetFilterCountValue(M4_TMR4_TypeDef *TMR4x,
en_timer4_pwm_ch_t enCh,
uint16_t u16Count)
{
__IO uint16_t *pu16PFSR = NULL;
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_PWM_CH(enCh));
/* Get pointer of current channel PWM register address */
pu16PFSR = (__IO uint16_t*)TMR4_PFSRx(TMR4x, enCh);
*pu16PFSR =u16Count;
enRet = Ok;
}
return enRet;
}
//@} // Timer4PwmGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,589 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_timer4_sevt.c
**
** A detailed description is available at
** @link Timer4SevtGroup Timer4SEVT description @endlink
**
** - 2018-11-02 CDT First version for Device Driver Library of Timer4SEVT.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_timer4_sevt.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup Timer4SevtGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter validity check for Timer4 unit */
#define IS_VALID_TIMER4(__TMRx__) \
( (M4_TMR41 == (__TMRx__)) || \
(M4_TMR42 == (__TMRx__)) || \
(M4_TMR43 == (__TMRx__)))
/*!< Parameter validity check for SEVT channel */
#define IS_VALID_SEVT_CH(x) \
( (Timer4SevtCh0 == (x)) || \
(Timer4SevtCh1 == (x)) || \
(Timer4SevtCh2 == (x)) || \
(Timer4SevtCh3 == (x)) || \
(Timer4SevtCh4 == (x)) || \
(Timer4SevtCh5 == (x)))
/*!< Parameter validity check for adct buffer mode */
#define IS_VALID_SEVT_BUF_MODE(x) \
( (SevtBufDisable == (x)) || \
(SevtBufCntZero == (x)) || \
(SevtBufCntPeak == (x)) || \
(SevtBufCntZeroOrCntPeak == (x)) || \
(SevtBufCntZeroZicZero == (x)) || \
(SevtBufCntPeakPicZero == (x)) || \
(SevtBufCntZeroZicZeroOrCntPeakPicZero == (x)))
/*!< Parameter validity check for SEVT trigger event */
#define IS_VALID_SEVT_TRG_EVT(x) \
( (SevtTrgEvtSCMUH == (x)) || \
(SevtTrgEvtSCMUL == (x)) || \
(SevtTrgEvtSCMVH == (x)) || \
(SevtTrgEvtSCMVL == (x)) || \
(SevtTrgEvtSCMWH == (x)) || \
(SevtTrgEvtSCMWL == (x)))
/*!< Parameter validity check for SEVT OCCR selection */
#define IS_VALID_SEVT_OCCR_SEL(x) \
( (SevtSelOCCRxh == (x)) || \
(SevtSelOCCRxl == (x)))
/*!< Parameter validity check for SEVT running mode */
#define IS_VALID_SEVT_MODE(x) \
( (SevtDelayTrigMode == (x)) || \
(SevtCompareTrigMode == (x)))
/*!< Parameter validity check for SEVT mask time */
#define IS_VALID_SEVT_MSK(x) \
( (Timer4SevtMask0 == (x)) || \
(Timer4SevtMask1 == (x)) || \
(Timer4SevtMask2 == (x)) || \
(Timer4SevtMask3 == (x)) || \
(Timer4SevtMask4 == (x)) || \
(Timer4SevtMask5 == (x)) || \
(Timer4SevtMask6 == (x)) || \
(Timer4SevtMask7 == (x)) || \
(Timer4SevtMask8 == (x)) || \
(Timer4SevtMask9 == (x)) || \
(Timer4SevtMask10 == (x)) || \
(Timer4SevtMask11 == (x)) || \
(Timer4SevtMask12 == (x)) || \
(Timer4SevtMask13 == (x)) || \
(Timer4SevtMask14 == (x)) || \
(Timer4SevtMask15 == (x)))
/*!< Get the specified register address of the specified Timer4 unit */
#define TMR4_SCCRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->SCCRUH + ((uint32_t)(__CH__))*4ul)
#define TMR4_SCSRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->SCSRUH + ((uint32_t)(__CH__))*4ul)
#define TMR4_SCMRx(__TMR4x__, __CH__) ((uint32_t)&(__TMR4x__)->SCMRUH + ((uint32_t)(__CH__))*4ul)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initialize a Special-Event channel
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Timer4 SEVT channel
** \arg Timer4SevtCh0 Timer4 SEVT channel:0
** \arg Timer4SevtCh1 Timer4 SEVT channel:1
** \arg Timer4SevtCh2 Timer4 SEVT channel:2
** \arg Timer4SevtCh3 Timer4 SEVT channel:3
** \arg Timer4SevtCh4 Timer4 SEVT channel:4
** \arg Timer4SevtCh5 Timer4 SEVT channel:5
** \param [in] pstcInitCfg The pointer of SEVT configure structure
** \arg This parameter detail refer @ref stc_timer4_sevt_init_t
**
** \retval Ok Initialize successfully
** \retval ErrorInvalidParameter If one of following conditions are met:
** - TMR4x is invalid
** - pstcInitCfg == NULL
** - enCh is invalid
** - Other invalid configuration
**
******************************************************************************/
en_result_t TIMER4_SEVT_Init(M4_TMR4_TypeDef *TMR4x,
en_timer4_sevt_ch_t enCh,
const stc_timer4_sevt_init_t *pstcInitCfg)
{
__IO uint16_t *pu16SCCR = NULL;
__IO stc_tmr4_scsr_field_t stcSCSR_f;
__IO stc_tmr4_scmr_field_t stcSCMR_f;
__IO stc_tmr4_scsr_field_t *pstcSCSR_f = NULL;
__IO stc_tmr4_scmr_field_t *pstcSCMR_f = NULL;
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x && pstcInitCfg pointer */
if ((IS_VALID_TIMER4(TMR4x)) && (NULL != pstcInitCfg))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
DDL_ASSERT(IS_VALID_SEVT_MODE(pstcInitCfg->enMode));
DDL_ASSERT(IS_VALID_SEVT_BUF_MODE(pstcInitCfg->enBuf));
DDL_ASSERT(IS_VALID_SEVT_MSK(pstcInitCfg->enMaskTimes));
DDL_ASSERT(IS_VALID_SEVT_TRG_EVT(pstcInitCfg->enTrigEvt));
DDL_ASSERT(IS_VALID_SEVT_OCCR_SEL(pstcInitCfg->enOccrSel));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enCmpAmcZicCmd));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcInitCfg->enCmpAmcPicCmd));
enRet = Ok;
/* Get actual address of register list of current channel */
pu16SCCR = (__IO uint16_t*)TMR4_SCCRx(TMR4x, enCh);
pstcSCSR_f = (__IO stc_tmr4_scsr_field_t*)TMR4_SCSRx(TMR4x, enCh);
pstcSCMR_f = (__IO stc_tmr4_scmr_field_t*)TMR4_SCMRx(TMR4x, enCh);
/* Configure default parameter */
*pu16SCCR = (uint16_t)0u;
*(__IO uint16_t*)pstcSCSR_f = (uint16_t)0x0000u;
*(__IO uint16_t*)pstcSCMR_f = (uint16_t)0xFF00u;
switch (pstcInitCfg->enBuf)
{
case SevtBufDisable:
stcSCSR_f.BUFEN = (uint16_t)0u;
stcSCSR_f.LMC = (uint16_t)0u;
break;
case SevtBufCntZero:
stcSCSR_f.BUFEN = (uint16_t)1u;
stcSCSR_f.LMC = (uint16_t)0u;
break;
case SevtBufCntPeak:
stcSCSR_f.BUFEN = (uint16_t)2u;
stcSCSR_f.LMC = (uint16_t)0u;
break;
case SevtBufCntZeroOrCntPeak:
stcSCSR_f.BUFEN = (uint16_t)3u;
stcSCSR_f.LMC = (uint16_t)0u;
break;
case SevtBufCntZeroZicZero:
stcSCSR_f.BUFEN = (uint16_t)1u;
stcSCSR_f.LMC = (uint16_t)1u;
break;
case SevtBufCntPeakPicZero:
stcSCSR_f.BUFEN = (uint16_t)2u;
stcSCSR_f.LMC = (uint16_t)1u;
break;
case SevtBufCntZeroZicZeroOrCntPeakPicZero:
stcSCSR_f.BUFEN = (uint16_t)3u;
stcSCSR_f.LMC = (uint16_t)1u;
break;
default:
enRet = ErrorInvalidParameter;
break;
}
if (Ok == enRet)
{
/* Configure start trigger output channel number */
stcSCSR_f.EVTOS = (uint16_t)(pstcInitCfg->enTrigEvt);
/* Select SEVT running mode */
stcSCSR_f.EVTMS = (uint16_t)(pstcInitCfg->enMode);
/* select OCO OCCR register: OCCR(x) */
stcSCSR_f.EVTDS = (uint16_t)(pstcInitCfg->enOccrSel);
/* Set the comparison with CNT interrupt mask counter */
stcSCMR_f.AMC = (uint16_t)(pstcInitCfg->enMaskTimes);
stcSCMR_f.MZCE = (uint16_t)(pstcInitCfg->enCmpAmcZicCmd);
stcSCMR_f.MPCE = (uint16_t)(pstcInitCfg->enCmpAmcPicCmd);
*pstcSCSR_f = stcSCSR_f;
*pstcSCMR_f = stcSCMR_f;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief De-Initialize a SEVT channel
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Timer4 SEVT channel
** \arg Timer4SevtCh0 Timer4 SEVT channel:0
** \arg Timer4SevtCh1 Timer4 SEVT channel:1
** \arg Timer4SevtCh2 Timer4 SEVT channel:2
** \arg Timer4SevtCh3 Timer4 SEVT channel:3
** \arg Timer4SevtCh4 Timer4 SEVT channel:4
** \arg Timer4SevtCh5 Timer4 SEVT channel:5
**
** \retval Ok De-Initialize successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_SEVT_DeInit(M4_TMR4_TypeDef *TMR4x,
en_timer4_sevt_ch_t enCh)
{
__IO uint16_t *pu16SCCR = NULL;
__IO stc_tmr4_scsr_field_t *pstcSCSR_f = NULL;
__IO stc_tmr4_scmr_field_t *pstcSCMR_f = NULL;
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
/* Get actual address of register list of current channel */
pu16SCCR = (__IO uint16_t*)TMR4_SCCRx(TMR4x, enCh);
pstcSCSR_f = (__IO stc_tmr4_scsr_field_t*)TMR4_SCSRx(TMR4x, enCh);
pstcSCMR_f = (__IO stc_tmr4_scmr_field_t*)TMR4_SCMRx(TMR4x, enCh);
/* Configure default parameter */
*pu16SCCR = 0u;
*(__IO uint16_t*)pstcSCSR_f = (uint16_t)0x0000u;
*(__IO uint16_t*)pstcSCMR_f = (uint16_t)0xFF00u;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set Timer4 SEVT trigger event.
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Timer4 SEVT channel
** \arg Timer4SevtCh0 Timer4 SEVT channel:0
** \arg Timer4SevtCh1 Timer4 SEVT channel:1
** \arg Timer4SevtCh2 Timer4 SEVT channel:2
** \arg Timer4SevtCh3 Timer4 SEVT channel:3
** \arg Timer4SevtCh4 Timer4 SEVT channel:4
** \arg Timer4SevtCh5 Timer4 SEVT channel:5
** \param [in] enTrgEvt Timer4 Special-EVT Event
** \arg SevtTrgEvtSCMUH Timer4 Special-EVT Event: TMR4_Ux_SCMUH
** \arg SevtTrgEvtSCMUL Timer4 Special-EVT Event: TMR4_Ux_SCMUL
** \arg SevtTrgEvtSCMVH Timer4 Special-EVT Event: TMR4_Ux_SCMVH
** \arg SevtTrgEvtSCMVL Timer4 Special-EVT Event: TMR4_Ux_SCMVL
** \arg SevtTrgEvtSCMWH Timer4 Special-EVT Event: TMR4_Ux_SCMWH
** \arg SevtTrgEvtSCMWL Timer4 Special-EVT Event: TMR4_Ux_SCMWL
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_SEVT_SetTriggerEvent(M4_TMR4_TypeDef *TMR4x,
en_timer4_sevt_ch_t enCh,
en_timer4_sevt_trigger_evt_t enTrgEvt)
{
__IO stc_tmr4_scsr_field_t *pstcSCSR_f = NULL;
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
DDL_ASSERT(IS_VALID_SEVT_TRG_EVT(enTrgEvt));
/* Get actual address of register list of current channel */
pstcSCSR_f = (__IO stc_tmr4_scsr_field_t*)TMR4_SCSRx(TMR4x, enCh);
pstcSCSR_f->EVTOS = (uint16_t)(enTrgEvt);
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Set Timer4 SEVT trigger condition.
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Timer4 SEVT channel
** \arg Timer4SevtCh0 Timer4 SEVT channel:0
** \arg Timer4SevtCh1 Timer4 SEVT channel:1
** \arg Timer4SevtCh2 Timer4 SEVT channel:2
** \arg Timer4SevtCh3 Timer4 SEVT channel:3
** \arg Timer4SevtCh4 Timer4 SEVT channel:4
** \arg Timer4SevtCh5 Timer4 SEVT channel:5
** \param [in] pstcTrigCond The pointer of SEVT trigger condition structure
** \arg This parameter detail refer @ref stc_timer4_sevt_trigger_cond_t
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_SEVT_SetTriggerCond(M4_TMR4_TypeDef *TMR4x,
en_timer4_sevt_ch_t enCh,
const stc_timer4_sevt_trigger_cond_t *pstcTrigCond)
{
__IO stc_tmr4_scsr_field_t *pstcSCSR_f = NULL;
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcTrigCond->enUpMatchCmd));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcTrigCond->enZeroMatchCmd));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcTrigCond->enDownMatchCmd));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcTrigCond->enPeakMatchCmd));
/* Get actual address of register list of current channel */
pstcSCSR_f = (__IO stc_tmr4_scsr_field_t*)TMR4_SCSRx(TMR4x, enCh);
pstcSCSR_f->PEN = (uint16_t)(pstcTrigCond->enPeakMatchCmd);
pstcSCSR_f->ZEN = (uint16_t)(pstcTrigCond->enZeroMatchCmd);
pstcSCSR_f->UEN = (uint16_t)(pstcTrigCond->enUpMatchCmd);
pstcSCSR_f->DEN = (uint16_t)(pstcTrigCond->enDownMatchCmd);
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Write compare or delay value to Timer4 SEVT
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Timer4 SEVT channel
** \arg Timer4SevtCh0 Timer4 SEVT channel:0
** \arg Timer4SevtCh1 Timer4 SEVT channel:1
** \arg Timer4SevtCh2 Timer4 SEVT channel:2
** \arg Timer4SevtCh3 Timer4 SEVT channel:3
** \arg Timer4SevtCh4 Timer4 SEVT channel:4
** \arg Timer4SevtCh5 Timer4 SEVT channel:5
** \param [in] u16SccrVal Timer4 SEVT compare value
**
** \retval Ok Compare or delay value to Timer4 SEVT is set
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_SEVT_WriteSCCR(M4_TMR4_TypeDef *TMR4x,
en_timer4_sevt_ch_t enCh,
uint16_t u16SccrVal)
{
__IO uint16_t *pu16SCCR = NULL;
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* check parameters */
DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
/* Get actual address of register list of current channel */
pu16SCCR = (__IO uint16_t*)TMR4_SCCRx(TMR4x, enCh);
*pu16SCCR = u16SccrVal;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Read compare value or delay value of ATVR
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Timer4 SEVT channel
** \arg Timer4SevtCh0 Timer4 SEVT channel:0
** \arg Timer4SevtCh1 Timer4 SEVT channel:1
** \arg Timer4SevtCh2 Timer4 SEVT channel:2
** \arg Timer4SevtCh3 Timer4 SEVT channel:3
** \arg Timer4SevtCh4 Timer4 SEVT channel:4
** \arg Timer4SevtCh5 Timer4 SEVT channel:5
**
** \retval Value of register SCCR
**
******************************************************************************/
uint16_t TIMER4_SEVT_ReadSCCR(M4_TMR4_TypeDef *TMR4x,
en_timer4_sevt_ch_t enCh)
{
__IO uint16_t *pu16SCCR = NULL;
/* check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
/* Get actual address of register list of current channel */
pu16SCCR = (__IO uint16_t*)TMR4_SCCRx(TMR4x, enCh);
return *pu16SCCR;
}
/**
*******************************************************************************
** \brief Set Timer4 SEVT trigger event.
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Timer4 SEVT channel
** \arg Timer4SevtCh0 Timer4 SEVT channel:0
** \arg Timer4SevtCh1 Timer4 SEVT channel:1
** \arg Timer4SevtCh2 Timer4 SEVT channel:2
** \arg Timer4SevtCh3 Timer4 SEVT channel:3
** \arg Timer4SevtCh4 Timer4 SEVT channel:4
** \arg Timer4SevtCh5 Timer4 SEVT channel:5
** \param [in] enMaskTimes Timer4 Special-EVT event mask times
** \arg Timer4SevtMask0 Mask 0 time.
** \arg Timer4SevtMask1 Mask 1 times.
** \arg Timer4SevtMask2 Mask 2 times.
** \arg Timer4SevtMask3 Mask 3 times.
** \arg Timer4SevtMask4 Mask 4 times.
** \arg Timer4SevtMask5 Mask 5 times.
** \arg Timer4SevtMask6 Mask 6 times.
** \arg Timer4SevtMask7 Mask 7 times.
** \arg Timer4SevtMask8 Mask 8 times.
** \arg Timer4SevtMask9 Mask 9 times.
** \arg Timer4SevtMask10 Mask 10 times
** \arg Timer4SevtMask11 Mask 11 times
** \arg Timer4SevtMask12 Mask 12 times
** \arg Timer4SevtMask13 Mask 13 times
** \arg Timer4SevtMask14 Mask 14 times
** \arg Timer4SevtMask15 Mask 15 times
**
** \retval Ok Set successfully.
** \retval ErrorInvalidParameter TMR4x is invalid
**
******************************************************************************/
en_result_t TIMER4_SEVT_SetMaskTimes(M4_TMR4_TypeDef *TMR4x,
en_timer4_sevt_ch_t enCh,
en_timer4_sevt_mask_t enMaskTimes)
{
__IO stc_tmr4_scmr_field_t *pstcSCMR_f = NULL;
en_result_t enRet = ErrorInvalidParameter;
/* Check TMR4x pointer */
if (IS_VALID_TIMER4(TMR4x))
{
/* Check parameters */
DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
DDL_ASSERT(IS_VALID_SEVT_MSK(enMaskTimes));
/* Get actual address of register list of current channel */
pstcSCMR_f = (__IO stc_tmr4_scmr_field_t*)TMR4_SCMRx(TMR4x, enCh);
pstcSCMR_f->AMC = (uint16_t)(enMaskTimes);
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Get Timer4 SEVT mask count.
**
** \param [in] TMR4x Pointer to Timer4 instance register base
** \arg M4_TMR41 Timer4 unit 1 instance register base
** \arg M4_TMR42 Timer4 unit 2 instance register base
** \arg M4_TMR43 Timer4 unit 3 instance register base
** \param [in] enCh Timer4 SEVT channel
** \arg Timer4SevtCh0 Timer4 SEVT channel:0
** \arg Timer4SevtCh1 Timer4 SEVT channel:1
** \arg Timer4SevtCh2 Timer4 SEVT channel:2
** \arg Timer4SevtCh3 Timer4 SEVT channel:3
** \arg Timer4SevtCh4 Timer4 SEVT channel:4
** \arg Timer4SevtCh5 Timer4 SEVT channel:5
**
** \retval Timer4SevtMask0 Mask 0 time.
** \retval Timer4SevtMask1 Mask 1 times.
** \retval Timer4SevtMask2 Mask 2 times.
** \retval Timer4SevtMask3 Mask 3 times.
** \retval Timer4SevtMask4 Mask 4 times.
** \retval Timer4SevtMask5 Mask 5 times.
** \retval Timer4SevtMask6 Mask 6 times.
** \retval Timer4SevtMask7 Mask 7 times.
** \retval Timer4SevtMask8 Mask 8 times.
** \retval Timer4SevtMask9 Mask 9 times.
** \retval Timer4SevtMask10 Mask 10 times
** \retval Timer4SevtMask11 Mask 11 times
** \retval Timer4SevtMask12 Mask 12 times
** \retval Timer4SevtMask13 Mask 13 times
** \retval Timer4SevtMask14 Mask 14 times
** \retval Timer4SevtMask15 Mask 15 times
**
******************************************************************************/
en_timer4_sevt_mask_t TIMER4_SEVT_GetMaskTimes(M4_TMR4_TypeDef *TMR4x,
en_timer4_sevt_ch_t enCh)
{
__IO stc_tmr4_scmr_field_t *pstcSCMR_f = NULL;
/* Check parameters */
DDL_ASSERT(IS_VALID_TIMER4(TMR4x));
DDL_ASSERT(IS_VALID_SEVT_CH(enCh));
/* Get actual address of register list of current channel */
pstcSCMR_f = (__IO stc_tmr4_scmr_field_t*)TMR4_SCMRx(TMR4x, enCh);
return (en_timer4_sevt_mask_t)pstcSCMR_f->AMC;
}
//@} // Timer4SevtGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,260 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_trng.c
**
** A detailed description is available at
** @link TrngGroup Trng description @endlink
**
** - 2018-10-20 CDT First version for Device Driver Library of Trng.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_trng.h"
#include "hc32f460_utility.h"
#include <system_hc32f460.h>
/**
*******************************************************************************
** \addtogroup TrngGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*! Parameter validity check for TRNG load control. */
#define IS_TRNG_LOAD_CTRL(CTRL) \
( ((CTRL) == TrngLoadNewInitValue_Enable) || \
((CTRL) == TrngLoadNewInitValue_Disable))
/*! Parameter validity check for TRNG shift count. */
#define IS_TRNG_SHIFT_COUNT(COUNT) \
( ((COUNT) == TrngShiftCount_32) || \
((COUNT) == TrngShiftCount_64) || \
((COUNT) == TrngShiftCount_128) || \
((COUNT) == TrngShiftCount_256))
#define RANDOM_NUM_LENGTH (2u)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initializes the TRNG.
**
** \param [in] pstcInit Pointer to TRNG initialization structure.
** \arg enLoadCtrl
** \- TrngLoadNewInitValue_Enable Data register load new initial value before
** random number is generated.
** \- TrngLoadNewInitValue_Disable Data register do not load new initial value
** before random number is generated.
**
** \arg enShiftCount Shift count control bit when capturing random noise.
** \- TrngShiftCount_32 Shift 32 times.
** \- TrngShiftCount_64 Shift 64 times.
** \- TrngShiftCount_128 Shift 128 times.
** \- TrngShiftCount_256 Shift 256 times.
**
** \retval Ok No error occurred.
** \retval ErrorInvalidParameter Parameter error.
**
******************************************************************************/
en_result_t TRNG_Init(const stc_trng_init_t *pstcInit)
{
en_result_t enRet = ErrorInvalidParameter;
if (NULL != pstcInit)
{
/* Parameter validity check */
DDL_ASSERT(IS_TRNG_LOAD_CTRL(pstcInit->enLoadCtrl));
DDL_ASSERT(IS_TRNG_SHIFT_COUNT(pstcInit->enShiftCount));
/* Stop TRNG generating*/
bM4_TRNG_CR_RUN = 0u;
/* Turn off TRNG circuit */
bM4_TRNG_CR_EN = 0u;
M4_TRNG->MR_f.LOAD = pstcInit->enLoadCtrl;
M4_TRNG->MR_f.CNT = pstcInit->enShiftCount;
enRet = Ok;
}
return enRet;
}
/**
*******************************************************************************
** \brief Deinitializes the TRNG.
**
** \param None.
**
** \retval None.
**
******************************************************************************/
void TRNG_DeInit(void)
{
/* Stop TRNG generating*/
bM4_TRNG_CR_RUN = 0u;
/* Turn off TRNG circuit */
bM4_TRNG_CR_EN = 0u;
/* Set the value of all registers to the reset value. */
M4_TRNG->CR = 0u;
M4_TRNG->MR = 0x12ul;
M4_TRNG->DR0 = 0x08000000ul;
M4_TRNG->DR0 = 0x08000200ul;
}
/**
*******************************************************************************
** \brief Start TRNG and generate random number.
**
** \param [out] pu32Random The destination address where the random
** number will be stored.
** \param [in] u8Length Random number length(in word).
** TRNG generates two random numbers(2 words) at one time.
** u8Length >= 2, both random numbers will be read.
** u8Length < 2, only one random number will be read.
** \param [in] u32Timeout Timeout value.
**
** \retval Ok No error occurred.
** \retval ErrorTimeout TRNG works timeout.
** \retval ErrorInvalidParameter Parameter error.
**
******************************************************************************/
en_result_t TRNG_Generate(uint32_t *pu32Random, uint8_t u8Length, uint32_t u32Timeout)
{
en_result_t enRet = ErrorInvalidParameter;
uint32_t u32TrngTimeout;
__IO uint32_t u32TimeCount;
if ((NULL != pu32Random) && (0u != u32Timeout) && (0u != u8Length))
{
/* 10 is the number of required instructions cycles for the below loop statement. */
u32TrngTimeout = u32Timeout * (SystemCoreClock / 10u / 1000u);
/* Turn on TRNG circuit. */
bM4_TRNG_CR_EN = 1u;
/* Start TRNG to generate random number. */
bM4_TRNG_CR_RUN = 1u;
/* wait generation done and check if timeout. */
u32TimeCount = 0u;
enRet = ErrorTimeout;
while (u32TimeCount < u32TrngTimeout)
{
if (bM4_TRNG_CR_RUN == 0u)
{
enRet = Ok;
break;
}
u32TimeCount++;
}
if (Ok == enRet)
{
/* read the random number. */
pu32Random[0u] = M4_TRNG->DR0;
if (u8Length >= RANDOM_NUM_LENGTH)
{
pu32Random[1u] = M4_TRNG->DR1;
}
}
/* Stop TRNG generating. */
bM4_TRNG_CR_RUN = 0u;
/* Turn off TRNG circuit. */
bM4_TRNG_CR_EN = 0u;
}
return enRet;
}
/**
*******************************************************************************
** \brief Start TRNG only.
**
** \param None.
**
** \retval None.
**
******************************************************************************/
void TRNG_StartIT(void)
{
/* Turn on TRNG circuit. */
bM4_TRNG_CR_EN = 1u;
/* Start TRNG to generate random number. */
bM4_TRNG_CR_RUN = 1u;
}
/**
*******************************************************************************
** \brief Get random number.
**
** \param [out] pu32Random The destination address where the random
** number will be stored.
** \param [in] u8Length Random number length(in word).
** TRNG generates two random numbers(2 words) at one time.
** u8Length >= 2, both random numbers will be read.
** u8Length < 2, only one random number will be read.
**
** \retval None.
**
******************************************************************************/
void TRNG_GetRandomNum(uint32_t *pu32Random, uint8_t u8Length)
{
if ((NULL != pu32Random) && (0u != u8Length))
{
pu32Random[0u] = M4_TRNG->DR0;
if (u8Length >= RANDOM_NUM_LENGTH)
{
pu32Random[1u] = M4_TRNG->DR1;
}
/* Stop TRNG generating */
bM4_TRNG_CR_RUN = 0u;
/* Turn off TRNG circuit */
bM4_TRNG_CR_EN = 0u;
}
}
//@} // TrngGroup
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,526 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_utility.c
**
** A detailed description is available at
** @link DdlUtilityGroup Ddl Utility description @endlink
**
** - 2018-11-02 CDT First version for Device Driver Library Utility.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_utility.h"
#if defined(DDL_UTILITY_ENABLE)
asdf
/**
*******************************************************************************
** \addtogroup DdlUtilityGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#if defined(PRINT_ENABLE)
/*!< Parameter valid check for USART Instances. */
#define IS_VALID_UART(x) \
( (M4_USART1 == (x)) || \
(M4_USART2 == (x)) || \
(M4_USART3 == (x)) || \
(M4_USART4 == (x)))
#define UART_EnableClk(x) \
do { \
if (M4_USART1 == (x)) \
{ \
M4_MSTP->FCG1_f.USART1 = 0ul; \
} \
else if (M4_USART2 == (x)) \
{ \
M4_MSTP->FCG1_f.USART2 = 0ul; \
} \
else if (M4_USART3 == (x)) \
{ \
M4_MSTP->FCG1_f.USART3 = 0ul; \
} \
else \
{ \
M4_MSTP->FCG1_f.USART4 = 0ul; \
} \
} while (0)
#endif
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
static uint32_t m_u32TickStep = 0UL;
static __IO uint32_t m_u32TickCount = 0UL;
#if defined(PRINT_ENABLE)
static M4_USART_TypeDef *m_PrintfDevice;
static uint32_t m_u32PrintfTimeout;
#endif
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
#if defined(PRINT_ENABLE)
/**
*******************************************************************************
** \brief UART transmit.
**
** \param [in] USARTx Pointer to USART instance register base
** This parameter can be one of the following values:
** @arg M4_USART1: USART unit 1 instance register base
** @arg M4_USART2: USART unit 2 instance register base
** @arg M4_USART3: USART unit 3 instance register base
** @arg M4_USART4: USART unit 4 instance register base
** \param [in] cData The data for transmitting
**
** \retval An en_result_t enumeration value:
** - Ok: Send successfully
** - ErrorTimeout: Send timeout
** - ErrorInvalidParameter: The parameter USARTx is invalid
**
******************************************************************************/
static en_result_t UartPutChar(M4_USART_TypeDef *USARTx, char cData)
{
uint32_t u32TxEmpty;
en_result_t enRet = ErrorInvalidParameter;
__IO uint32_t u32Timeout = m_u32PrintfTimeout;
if (NULL != USARTx)
{
/* Wait TX data register empty */
do
{
u32Timeout--;
u32TxEmpty = USARTx->SR_f.TXE;
} while ((u32Timeout > 0ul) && (0ul == u32TxEmpty));
if (u32TxEmpty > 0ul)
{
USARTx->DR = (uint32_t)cData;
enRet = Ok;
}
else
{
enRet = ErrorTimeout;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief Set synchronous clock mode baudrate
**
** \param [in] USARTx Pointer to USART instance register base
** This parameter can be one of the following values:
** @arg M4_USART1: USART unit 1 instance register base
** @arg M4_USART2: USART unit 2 instance register base
** @arg M4_USART3: USART unit 3 instance register base
** @arg M4_USART4: USART unit 4 instance register base
** \param [in] u32Baudrate Baudrate
**
** \retval Ok Configure successfully.
** \retval ErrorInvalidParameter USARTx is invalid
**
******************************************************************************/
static en_result_t SetUartBaudrate(M4_USART_TypeDef *USARTx, uint32_t u32Baudrate)
{
uint32_t B;
uint32_t C;
uint32_t OVER8;
float32_t DIV;
uint64_t u64Tmp;
uint32_t DIV_Integer;
uint32_t DIV_Fraction;
uint32_t u32PClk1;
uint32_t u32UartClk;
en_result_t enRet = ErrorInvalidParameter;
u32PClk1 = SystemCoreClock / (1ul << (M4_SYSREG->CMU_SCFGR_f.PCLK1S));
u32UartClk = u32PClk1 / (1ul << (2ul * (USARTx->PR_f.PSC)));
B = u32Baudrate;
C = u32UartClk;
DIV_Fraction = 0ul;
if ((0ul != C) && (0ul != B))
{
OVER8 = USARTx->CR1_f.OVER8;
/* FBME = 0 Calculation formula */
/* B = C / (8 * (2 - OVER8) * (DIV_Integer + 1)) */
/* DIV_Integer = (C / (B * 8 * (2 - OVER8))) - 1 */
DIV = ((float)C / ((float)B * 8.0f * (2.0f - (float)OVER8))) - 1.0f;
DIV_Integer = (uint32_t)(DIV);
if ((DIV < 0.0f) || (DIV_Integer > 0xFFul))
{
enRet = ErrorInvalidParameter;
}
else
{
if ((DIV - (float32_t)DIV_Integer) > 0.00001f)
{
/* FBME = 1 Calculation formula */
/* B = C * (128 + DIV_Fraction) / (8 * (2 - OVER8) * (DIV_Integer + 1) * 256) */
/* DIV_Fraction = ((8 * (2 - OVER8) * (DIV_Integer + 1) * 256 * B) / C) - 128 */
/* E = (C * (128 + DIV_Fraction) / (8 * (2 - OVER8) * (DIV_Integer + 1) * 256 * B)) - 1 */
/* DIV_Fraction = (((2 - OVER8) * (DIV_Integer + 1) * 2048 * B) / C) - 128 */
u64Tmp = (2u - (uint64_t)OVER8) * ((uint64_t)DIV_Integer + 1u) * (uint64_t)B;
DIV_Fraction = (uint32_t)(2048ul * u64Tmp/C - 128ul);
}
USARTx->CR1_f.FBME = (DIV_Fraction > 0UL) ? 1ul : 0ul;
USARTx->BRR_f.DIV_FRACTION = DIV_Fraction;
USARTx->BRR_f.DIV_INTEGER = DIV_Integer;
enRet = Ok;
}
}
return enRet;
}
#if defined ( __GNUC__ ) && !defined (__CC_ARM)
/**
*******************************************************************************
** \brief Re-target _write function.
**
** \param [in] fd
** \param [in] data
** \param [in] size
**
** \retval int32_t
**
******************************************************************************/
int32_t _write(int fd, char data[], int32_t size)
{
int32_t i = -1;
if (NULL != data)
{
(void)fd; /* Prevent unused argument compilation warning */
for (i = 0; i < size; i++)
{
if (Ok != UartPutChar(m_PrintfDevice, data[i]))
{
break;
}
}
}
return i ? i : -1;
}
#else
/**
*******************************************************************************
** \brief Re-target fputc function.
**
** \param [in] ch
** \param [in] f
**
** \retval int32_t
**
******************************************************************************/
int32_t fputc(int32_t ch, FILE *f)
{
(void)f; /* Prevent unused argument compilation warning */
return (Ok == UartPutChar(m_PrintfDevice, (char)ch)) ? ch: -1;
}
#endif
/**
*******************************************************************************
** \brief Debug printf initialization function
**
** \param [in] UARTx Pointer to USART instance register base
** This parameter can be one of the following values:
** @arg M4_USART1: USART unit 1 instance register base
** @arg M4_USART2: USART unit 2 instance register base
** @arg M4_USART3: USART unit 3 instance register base
** @arg M4_USART4: USART unit 4 instance register base
** \param [in] u32Baudrate Baudrate
** \param [in] PortInit The pointer of printf port initialization function
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t UART_PrintfInit(M4_USART_TypeDef *UARTx,
uint32_t u32Baudrate,
void (*PortInit)(void))
{
en_result_t enRet = ErrorInvalidParameter;
if (IS_VALID_UART(UARTx) && (0ul != u32Baudrate) && (NULL != PortInit))
{
/* Initialize port */
PortInit();
/* Enable clock */
UART_EnableClk(UARTx);
/* Initialize USART */
UARTx->CR1_f.ML = 0ul; /* LSB */
UARTx->CR1_f.MS = 0ul; /* UART mode */
UARTx->CR1_f.OVER8 = 1ul; /* 8bit sampling mode */
UARTx->CR1_f.M = 0ul; /* 8 bit data length */
UARTx->CR1_f.PCE = 0ul; /* no parity bit */
/* Set baudrate */
if(Ok != SetUartBaudrate(UARTx, u32Baudrate))
{
enRet = Error;
}
else
{
UARTx->CR2 = 0ul; /* 1 stop bit, single uart mode */
UARTx->CR3 = 0ul; /* CTS disable, Smart Card mode disable */
UARTx->CR1_f.TE = 1ul; /* TX enable */
m_PrintfDevice = UARTx;
m_u32PrintfTimeout = (SystemCoreClock / u32Baudrate);
}
}
return enRet;
}
#endif /* DDL_PRINT_ENABLE */
/**
*******************************************************************************
** \brief Delay function, delay 1ms approximately
**
** \param [in] u32Cnt ms
**
** \retval none
**
******************************************************************************/
void Ddl_Delay1ms(uint32_t u32Cnt)
{
volatile uint32_t i;
uint32_t u32Cyc;
u32Cyc = SystemCoreClock;
u32Cyc = u32Cyc / 10000ul;
while (u32Cnt-- > 0ul)
{
i = u32Cyc;
while (i-- > 0ul)
{
;
}
}
}
/**
*******************************************************************************
** \brief Delay function, delay 1us approximately
**
** \param [in] u32Cnt us
**
** \retval none
**
******************************************************************************/
void Ddl_Delay1us(uint32_t u32Cnt)
{
uint32_t u32Cyc;
volatile uint32_t i;
if(SystemCoreClock > 10000000ul)
{
u32Cyc = SystemCoreClock / 10000000ul;
while(u32Cnt-- > 0ul)
{
i = u32Cyc;
while (i-- > 0ul)
{
;
}
}
}
else
{
while(u32Cnt-- > 0ul)
{
;
}
}
}
/**
*******************************************************************************
** \brief This function Initializes the interrupt frequency of the SysTick.
**
** \param [in] u32Freq SysTick interrupt frequency (1 to 1000).
**
** \retval Ok SysTick Initializes succeed
** \retval Error SysTick Initializes failed
**
******************************************************************************/
__WEAKDEF en_result_t SysTick_Init(uint32_t u32Freq)
{
en_result_t enRet = Error;
if ((0UL != u32Freq) && (u32Freq <= 1000UL))
{
m_u32TickStep = 1000UL / u32Freq;
/* Configure the SysTick interrupt */
if (0UL == SysTick_Config(SystemCoreClock / u32Freq))
{
enRet = Ok;
}
}
return enRet;
}
/**
*******************************************************************************
** \brief This function provides minimum delay (in milliseconds).
**
** \param [in] u32Delay Delay specifies the delay time.
**
** \retval None
**
******************************************************************************/
__WEAKDEF void SysTick_Delay(uint32_t u32Delay)
{
const uint32_t tickStart = SysTick_GetTick();
uint32_t tickEnd = u32Delay;
uint32_t tickMax;
if (m_u32TickStep != 0UL)
{
tickMax = 0xFFFFFFFFUL / m_u32TickStep * m_u32TickStep;
/* Add a freq to guarantee minimum wait */
if ((u32Delay >= tickMax) || ((tickMax - u32Delay) < m_u32TickStep))
{
tickEnd = tickMax;
}
while ((SysTick_GetTick() - tickStart) < tickEnd)
{
}
}
}
/**
*******************************************************************************
** \brief This function is called to increment a global variable "u32TickCount".
** \note This variable is incremented in SysTick ISR.
**
** \param None
**
** \retval None
**
******************************************************************************/
__WEAKDEF void SysTick_IncTick(void)
{
m_u32TickCount += m_u32TickStep;
}
/**
*******************************************************************************
** \brief Provides a tick value in millisecond.
**
** \param None
**
** \retval Tick value
**
******************************************************************************/
__WEAKDEF uint32_t SysTick_GetTick(void)
{
return m_u32TickCount;
}
/**
*******************************************************************************
** \brief Suspend SysTick increment.
**
** \param None
**
** \retval None
**
******************************************************************************/
__WEAKDEF void SysTick_Suspend(void)
{
/* Disable SysTick Interrupt */
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
}
/**
*******************************************************************************
** \brief Resume SysTick increment.
**
** \param None
**
** \retval None
**
******************************************************************************/
__WEAKDEF void SysTick_Resume(void)
{
/* Enable SysTick Interrupt */
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
}
/**
*******************************************************************************
** \brief ddl assert error handle function
**
** \param [in] file Point to the current assert the wrong file
** \param [in] line Point line assert the wrong file in the current
**
******************************************************************************/
#ifdef __DEBUG
__WEAKDEF void Ddl_AssertHandler(uint8_t *file, int16_t line)
{
/* Users can re-implement this function to print information */
#if defined(PRINT_ENABLE)
printf("Wrong parameters value: file %s on line %d\r\n", file, line);
#else
(void)file;
(void)line;
#endif
for (;;)
{
;
}
}
#endif /* __DEBUG */
//@} // DdlUtilityGroup
#endif /* DDL_UTILITY_ENABLE */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,250 @@
/*******************************************************************************
* 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
*/
/******************************************************************************/
/** \file hc32f460_wdt.c
**
** A detailed description is available at
** @link WdtGroup Watchdog Counter description @endlink
**
** - 2018-10-18 CDT First version for Device Driver Library of WDT.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32f460_wdt.h"
#include "hc32f460_utility.h"
/**
*******************************************************************************
** \addtogroup WdtGroup
******************************************************************************/
//@{
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*!< Parameter validity check for count cycle */
#define IS_VALID_COUNT_CYCLE(x) \
( (WdtCountCycle256 == (x)) || \
(WdtCountCycle4096 == (x)) || \
(WdtCountCycle16384 == (x)) || \
(WdtCountCycle65536 == (x)))
/*!< Parameter validity check for clock division */
#define IS_VALID_CLOCK_DIV(x) \
( (WdtPclk3Div4 == (x)) || \
(WdtPclk3Div64 == (x)) || \
(WdtPclk3Div128 == (x)) || \
(WdtPclk3Div256 == (x)) || \
(WdtPclk3Div512 == (x)) || \
(WdtPclk3Div1024 == (x)) || \
(WdtPclk3Div2048 == (x)) || \
(WdtPclk3Div8192 == (x)))
/*!< Parameter validity check for allow refresh percent range */
#define IS_VALID_ALLOW_REFRESH_RANGE(x) \
( (WdtRefresh100Pct == (x)) || \
(WdtRefresh0To25Pct == (x)) || \
(WdtRefresh25To50Pct == (x)) || \
(WdtRefresh0To50Pct == (x)) || \
(WdtRefresh50To75Pct == (x)) || \
(WdtRefresh0To25PctAnd50To75Pct == (x)) || \
(WdtRefresh25To75Pct == (x)) || \
(WdtRefresh0To75Pct == (x)) || \
(WdtRefresh75To100Pct == (x)) || \
(WdtRefresh0To25PctAnd75To100Pct == (x)) || \
(WdtRefresh25To50PctAnd75To100Pct == (x)) || \
(WdtRefresh0To50PctAnd75To100Pct == (x)) || \
(WdtRefresh50To100Pct == (x)) || \
(WdtRefresh0To25PctAnd50To100Pct == (x)) || \
(WdtRefresh25To100Pct == (x)) || \
(WdtRefresh0To100Pct == (x)))
/*!< Parameter validity check for event request type */
#define IS_VALID_EVENT_REQUEST_TYPE(x) \
( (WdtTriggerInterruptRequest == (x)) || \
(WdtTriggerResetRequest == (x)))
/*!< Parameter validity check for flag type */
#define IS_VALID_FLAG_TYPE(x) \
( (WdtFlagCountUnderflow == (x)) || \
(WdtFlagRefreshError == (x)))
/*!< WDT_RR register refresh key */
#define WDT_REFRESH_START_KEY ((uint16_t)0x0123)
#define WDT_REFRESH_END_KEY ((uint16_t)0x3210)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initialize WDT function
**
** \param [in] pstcWdtInit Pointer to WDT init configuration
** \arg See the struct #stc_wdt_init_t
**
** \retval Ok Process successfully done
** \retval Error Parameter error
**
******************************************************************************/
en_result_t WDT_Init(const stc_wdt_init_t *pstcWdtInit)
{
en_result_t enRet = Ok;
uint32_t regTemp;
if (NULL == pstcWdtInit)
{
enRet = Error;
}
else
{
/* Check parameters */
DDL_ASSERT(IS_VALID_COUNT_CYCLE(pstcWdtInit->enCountCycle));
DDL_ASSERT(IS_VALID_CLOCK_DIV(pstcWdtInit->enClkDiv));
DDL_ASSERT(IS_VALID_ALLOW_REFRESH_RANGE(pstcWdtInit->enRefreshRange));
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcWdtInit->enSleepModeCountEn));
DDL_ASSERT(IS_VALID_EVENT_REQUEST_TYPE(pstcWdtInit->enRequestType));
/* software start mode */
regTemp = ((((uint32_t)pstcWdtInit->enRequestType) << 31) | \
(((uint32_t)(bool)(!pstcWdtInit->enSleepModeCountEn)) << 16) | \
(((uint32_t)pstcWdtInit->enRefreshRange) << 8) | \
(((uint32_t)pstcWdtInit->enClkDiv) << 4) | \
((uint32_t)pstcWdtInit->enCountCycle));
/* store the new value */
M4_WDT->CR = regTemp;
}
return enRet;
}
/**
*******************************************************************************
** \brief WDT refresh counter(First refresh start count when software start)
**
** \param [in] None
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t WDT_RefreshCounter(void)
{
en_result_t enRet = Ok;
M4_WDT->RR = WDT_REFRESH_START_KEY;
M4_WDT->RR = WDT_REFRESH_END_KEY;
return enRet;
}
/**
*******************************************************************************
** \brief Get WDT counter current count value
**
** \param [in] None
**
** \retval uint16_t WDT counter current count value
**
******************************************************************************/
uint16_t WDT_GetCountValue(void)
{
return ((uint16_t)M4_WDT->SR_f.CNT);
}
/**
*******************************************************************************
** \brief Get WDT flag status
**
** \param [in] enFlag WDT flag type
** \arg WdtFlagCountUnderflow Count underflow flag
** \arg WdtFlagRefreshError Refresh error flag
**
** \retval Set Flag is set
** \retval Reset Flag is reset
**
******************************************************************************/
en_flag_status_t WDT_GetFlag(en_wdt_flag_type_t enFlag)
{
en_flag_status_t enFlagSta = Reset;
/* Check parameters */
DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
switch (enFlag)
{
case WdtFlagCountUnderflow:
enFlagSta = (en_flag_status_t)M4_WDT->SR_f.UDF;
break;
case WdtFlagRefreshError:
enFlagSta = (en_flag_status_t)M4_WDT->SR_f.REF;
break;
default:
break;
}
return enFlagSta;
}
/**
*******************************************************************************
** \brief Clear WDT flag status
**
** \param [in] enFlag WDT flag type
** \arg WdtFlagCountUnderflow Count underflow flag
** \arg WdtFlagRefreshError Refresh error flag
**
** \retval Ok Process successfully done
**
******************************************************************************/
en_result_t WDT_ClearFlag(en_wdt_flag_type_t enFlag)
{
en_result_t enRet = Ok;
/* Check parameters */
DDL_ASSERT(IS_VALID_FLAG_TYPE(enFlag));
switch (enFlag)
{
case WdtFlagCountUnderflow:
M4_WDT->SR_f.UDF = 0u;
break;
case WdtFlagRefreshError:
M4_WDT->SR_f.REF = 0u;
break;
default:
break;
}
return enRet;
}
//@} // WdtGroup
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/