rt-thread-official/bsp/imxrt/libraries/MIMXRT1170/MIMXRT1176/drivers/fsl_xecc.c

149 lines
4.7 KiB
C

/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_xecc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.xecc"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief XECC module initialization function.
*
* param base XECC base address.
*/
void XECC_Init(XECC_Type *base, const xecc_config_t *config)
{
/* Enable all the interrupt status */
base->ERR_STAT_EN = kXECC_AllInterruptsStatusEnable;
/* Clear all the interrupt status */
base->ERR_STATUS = kXECC_AllInterruptsFlag;
/* Disable all the interrpt */
base->ERR_SIG_EN = 0U;
/* Set ECC regions, which are 4KB aligned */
base->ECC_BASE_ADDR0 = config->Region0BaseAddress >> 12U;
base->ECC_END_ADDR0 = config->Region0EndAddress >> 12U;
base->ECC_BASE_ADDR1 = config->Region1BaseAddress >> 12U;
base->ECC_END_ADDR1 = config->Region1EndAddress >> 12U;
base->ECC_BASE_ADDR2 = config->Region2BaseAddress >> 12U;
base->ECC_END_ADDR2 = config->Region2EndAddress >> 12U;
base->ECC_BASE_ADDR3 = config->Region3BaseAddress >> 12U;
base->ECC_END_ADDR3 = config->Region3EndAddress >> 12U;
/* Enable ECC function */
base->ECC_CTRL = XECC_ECC_CTRL_ECC_EN(config->enableXECC);
base->ECC_CTRL |= XECC_ECC_CTRL_WECC_EN(config->enableWriteECC);
base->ECC_CTRL |= XECC_ECC_CTRL_RECC_EN(config->enableReadECC);
base->ECC_CTRL |= XECC_ECC_CTRL_SWAP_EN(config->enableSwap);
/* Make sure XECC register configuration operation has been done. */
__DSB();
}
/*!
* brief Deinitializes the XECC.
*
*/
void XECC_Deinit(XECC_Type *base)
{
/* Disable ECC function */
base->ECC_CTRL &= ~XECC_ECC_CTRL_ECC_EN(1);
}
void XECC_GetDefaultConfig(xecc_config_t *config)
{
assert(NULL != config);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
/* Default XECC function */
config->enableXECC = false;
/* Default write ECC function */
config->enableWriteECC = false;
/* Default read ECC function */
config->enableReadECC = false;
/* Default swap function */
config->enableSwap = false;
/* ECC region 0 base address */
config->Region0BaseAddress = 0U;
/* ECC region 0 end address */
config->Region0EndAddress = 0U;
/* ECC region 1 base address */
config->Region1BaseAddress = 0U;
/* ECC region 1 end address */
config->Region1EndAddress = 0U;
/* ECC region 2 base address */
config->Region2BaseAddress = 0U;
/* ECC region 2 end address */
config->Region2EndAddress = 0U;
/* ECC region 3 base address */
config->Region3BaseAddress = 0U;
/* ECC region 3 end address */
config->Region3EndAddress = 0U;
}
/* Mainly use for debug, it can be deprecated when release */
status_t XECC_ErrorInjection(XECC_Type *base, uint32_t errordata, uint8_t erroreccdata)
{
status_t status = kStatus_Success;
if ((errordata != 0x00U) || (erroreccdata != 0x00U))
{
/* error data injection */
base->ERR_DATA_INJ = errordata;
/* error ecc code injection */
base->ERR_ECC_INJ = erroreccdata;
/* Make sure injection operation has been done. */
__DSB();
}
else
{
status = kStatus_Fail;
}
return status;
}
void XECC_GetSingleErrorInfo(XECC_Type *base, xecc_single_error_info_t *info)
{
assert(info != NULL);
info->singleErrorAddress = base->SINGLE_ERR_ADDR;
info->singleErrorData = base->SINGLE_ERR_DATA;
info->singleErrorEccCode = base->SINGLE_ERR_ECC;
info->singleErrorBitField = base->SINGLE_ERR_BIT_FIELD;
info->singleErrorBitPos = base->SINGLE_ERR_POS;
}
void XECC_GetMultiErrorInfo(XECC_Type *base, xecc_multi_error_info_t *info)
{
assert(info != NULL);
info->multiErrorAddress = base->MULTI_ERR_ADDR;
info->multiErrorData = base->MULTI_ERR_DATA;
info->multiErrorEccCode = base->MULTI_ERR_ECC;
info->multiErrorBitField = base->MULTI_ERR_BIT_FIELD;
}