File indexing completed on 2025-05-11 08:23:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "fsl_mecc.h"
0010
0011
0012
0013
0014
0015
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.mecc"
0018 #endif
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 static uint32_t MECC_GetInstance(MECC_Type *base);
0031
0032
0033
0034
0035 static MECC_Type *const s_meccBases[] = MECC_BASE_PTRS;
0036
0037
0038
0039 static uint32_t MECC_GetInstance(MECC_Type *base)
0040 {
0041 uint32_t instance;
0042
0043
0044 for (instance = 0; instance < ARRAY_SIZE(s_meccBases); instance++)
0045 {
0046 if (s_meccBases[instance] == base)
0047 {
0048 break;
0049 }
0050 }
0051
0052 assert(instance < ARRAY_SIZE(s_meccBases));
0053
0054 return instance;
0055 }
0056
0057
0058
0059
0060
0061
0062 void MECC_Init(MECC_Type *base, mecc_config_t *config)
0063 {
0064 uint32_t instance = MECC_GetInstance(base);
0065 volatile uint64_t *ocramStartAddr = NULL;
0066
0067
0068 base->ERR_STAT_EN = kMECC_AllInterruptsStatusEnable;
0069
0070 base->ERR_STATUS = kMECC_AllInterruptsFlag;
0071
0072 base->ERR_SIG_EN = 0U;
0073
0074
0075 base->PIPE_ECC_EN = MECC_PIPE_ECC_EN_ECC_EN(config->enableMecc);
0076
0077 __DSB();
0078
0079 if (instance == (uint32_t)kMECC_Instance0)
0080 {
0081
0082
0083 ocramStartAddr = (uint64_t *)config->Ocram1StartAddress;
0084 while (ocramStartAddr < (uint64_t *)config->Ocram1EndAddress)
0085 {
0086 *ocramStartAddr = 0x00;
0087 ocramStartAddr++;
0088 }
0089 }
0090 else if (instance == (uint32_t)kMECC_Instance1)
0091 {
0092
0093
0094 ocramStartAddr = (uint64_t *)config->Ocram2StartAddress;
0095 while (ocramStartAddr < (uint64_t *)config->Ocram2EndAddress)
0096 {
0097 *ocramStartAddr = 0x00;
0098 ocramStartAddr++;
0099 }
0100 }
0101 else
0102 {
0103 ;
0104 }
0105 }
0106
0107
0108
0109
0110
0111 void MECC_Deinit(MECC_Type *base)
0112 {
0113
0114 base->PIPE_ECC_EN &= ~MECC_PIPE_ECC_EN_ECC_EN(1);
0115 }
0116
0117 void MECC_GetDefaultConfig(mecc_config_t *config)
0118 {
0119 assert(NULL != config);
0120
0121
0122 (void)memset(config, 0, sizeof(*config));
0123
0124
0125 config->enableMecc = false;
0126
0127 config->Ocram1StartAddress = 0x20240000;
0128
0129 config->Ocram1EndAddress = 0x202BFFFF;
0130
0131 config->Ocram1StartAddress = 0x202C0000;
0132
0133 config->Ocram1EndAddress = 0x2033FFFF;
0134 }
0135
0136
0137
0138
0139 status_t MECC_ErrorInjection(
0140 MECC_Type *base, uint32_t lowerrordata, uint32_t higherrordata, uint8_t eccdata, uint8_t banknumber)
0141 {
0142 status_t status = kStatus_Success;
0143
0144 switch (banknumber)
0145 {
0146 case kMECC_OcramBank0:
0147
0148 base->ERR_DATA_INJ_LOW0 = lowerrordata;
0149
0150 base->ERR_DATA_INJ_HIGH0 = higherrordata;
0151
0152 base->ERR_ECC_INJ0 = eccdata;
0153 break;
0154
0155 case kMECC_OcramBank1:
0156
0157 base->ERR_DATA_INJ_LOW1 = lowerrordata;
0158
0159 base->ERR_DATA_INJ_HIGH1 = higherrordata;
0160
0161 base->ERR_ECC_INJ1 = eccdata;
0162 break;
0163
0164 case kMECC_OcramBank2:
0165
0166 base->ERR_DATA_INJ_LOW2 = lowerrordata;
0167
0168 base->ERR_DATA_INJ_HIGH2 = higherrordata;
0169
0170 base->ERR_ECC_INJ2 = eccdata;
0171 break;
0172
0173 case kMECC_OcramBank3:
0174
0175 base->ERR_DATA_INJ_LOW3 = lowerrordata;
0176
0177 base->ERR_DATA_INJ_HIGH3 = higherrordata;
0178
0179 base->ERR_ECC_INJ3 = eccdata;
0180 break;
0181
0182 default:
0183 status = kStatus_MECC_BankMiss;
0184 break;
0185 }
0186
0187 return status;
0188 }
0189
0190 status_t MECC_GetSingleErrorInfo(MECC_Type *base, mecc_single_error_info_t *info, uint8_t banknumber)
0191 {
0192 assert(info != NULL);
0193 status_t status = kStatus_Success;
0194 uint8_t tempPosLow = 0U;
0195 uint8_t tempPosHigh = 0U;
0196 uint32_t counter = 0U;
0197
0198 switch (banknumber)
0199 {
0200 case kMECC_OcramBank0:
0201 info->singleErrorEccCode =
0202 (uint8_t)((base->SINGLE_ERR_ADDR_ECC0 & MECC_SINGLE_ERR_ADDR_ECC0_SINGLE_ERR_ECC_MASK) >>
0203 MECC_SINGLE_ERR_ADDR_ECC0_SINGLE_ERR_ECC_SHIFT);
0204 info->singleErrorAddress = (base->SINGLE_ERR_ADDR_ECC0 & MECC_SINGLE_ERR_ADDR_ECC0_SINGLE_ERR_ADDR_MASK) >>
0205 MECC_SINGLE_ERR_ADDR_ECC0_SINGLE_ERR_ADDR_SHIFT;
0206 info->singleErrorDataLow = base->SINGLE_ERR_DATA_LOW0;
0207 info->singleErrorDataHigh = base->SINGLE_ERR_DATA_HIGH0;
0208 tempPosLow = (uint8_t)base->SINGLE_ERR_POS_LOW0;
0209 tempPosHigh = (uint8_t)base->SINGLE_ERR_POS_HIGH0;
0210 break;
0211
0212 case kMECC_OcramBank1:
0213 info->singleErrorEccCode =
0214 (uint8_t)((base->SINGLE_ERR_ADDR_ECC1 & MECC_SINGLE_ERR_ADDR_ECC1_SINGLE_ERR_ECC_MASK) >>
0215 MECC_SINGLE_ERR_ADDR_ECC1_SINGLE_ERR_ECC_SHIFT);
0216 info->singleErrorAddress = (base->SINGLE_ERR_ADDR_ECC1 & MECC_SINGLE_ERR_ADDR_ECC1_SINGLE_ERR_ADDR_MASK) >>
0217 MECC_SINGLE_ERR_ADDR_ECC1_SINGLE_ERR_ADDR_SHIFT;
0218 info->singleErrorDataLow = base->SINGLE_ERR_DATA_LOW1;
0219 info->singleErrorDataHigh = base->SINGLE_ERR_DATA_HIGH1;
0220 tempPosLow = (uint8_t)base->SINGLE_ERR_POS_LOW1;
0221 tempPosHigh = (uint8_t)base->SINGLE_ERR_POS_HIGH1;
0222 break;
0223
0224 case kMECC_OcramBank2:
0225 info->singleErrorEccCode =
0226 (uint8_t)((base->SINGLE_ERR_ADDR_ECC2 & MECC_SINGLE_ERR_ADDR_ECC2_SINGLE_ERR_ECC_MASK) >>
0227 MECC_SINGLE_ERR_ADDR_ECC2_SINGLE_ERR_ECC_SHIFT);
0228 info->singleErrorAddress = (base->SINGLE_ERR_ADDR_ECC2 & MECC_SINGLE_ERR_ADDR_ECC2_SINGLE_ERR_ADDR_MASK) >>
0229 MECC_SINGLE_ERR_ADDR_ECC2_SINGLE_ERR_ADDR_SHIFT;
0230 info->singleErrorDataLow = base->SINGLE_ERR_DATA_LOW2;
0231 info->singleErrorDataHigh = base->SINGLE_ERR_DATA_HIGH2;
0232 tempPosLow = (uint8_t)base->SINGLE_ERR_POS_LOW2;
0233 tempPosHigh = (uint8_t)base->SINGLE_ERR_POS_HIGH2;
0234 break;
0235
0236 case kMECC_OcramBank3:
0237 info->singleErrorEccCode =
0238 (uint8_t)((base->SINGLE_ERR_ADDR_ECC3 & MECC_SINGLE_ERR_ADDR_ECC3_SINGLE_ERR_ECC_MASK) >>
0239 MECC_SINGLE_ERR_ADDR_ECC3_SINGLE_ERR_ECC_SHIFT);
0240 info->singleErrorAddress = (base->SINGLE_ERR_ADDR_ECC3 & MECC_SINGLE_ERR_ADDR_ECC3_SINGLE_ERR_ADDR_MASK) >>
0241 MECC_SINGLE_ERR_ADDR_ECC3_SINGLE_ERR_ADDR_SHIFT;
0242 info->singleErrorDataLow = base->SINGLE_ERR_DATA_LOW3;
0243 info->singleErrorDataHigh = base->SINGLE_ERR_DATA_HIGH3;
0244 tempPosLow = (uint8_t)base->SINGLE_ERR_POS_LOW3;
0245 tempPosHigh = (uint8_t)base->SINGLE_ERR_POS_HIGH3;
0246 break;
0247
0248 default:
0249 status = kStatus_MECC_BankMiss;
0250 break;
0251 }
0252
0253 while (tempPosLow > 0U)
0254 {
0255 tempPosLow = tempPosLow >> 1;
0256 counter++;
0257 }
0258
0259 if (counter == 0U)
0260 {
0261 info->singleErrorPosLow = 0;
0262 }
0263 else
0264 {
0265 info->singleErrorPosLow = counter - 1U;
0266 }
0267
0268 counter = 0U;
0269 while (tempPosHigh > 0U)
0270 {
0271 tempPosHigh = tempPosHigh >> 1;
0272 counter++;
0273 }
0274
0275 if (counter == 0U)
0276 {
0277 info->singleErrorPosHigh = 0;
0278 }
0279 else
0280 {
0281 info->singleErrorPosHigh = counter - 1U;
0282 }
0283
0284 return status;
0285 }
0286
0287 status_t MECC_GetMultiErrorInfo(MECC_Type *base, mecc_multi_error_info_t *info, uint8_t banknumber)
0288 {
0289 assert(info != NULL);
0290 status_t status = kStatus_Success;
0291
0292 switch (banknumber)
0293 {
0294 case kMECC_OcramBank0:
0295 info->multiErrorEccCode =
0296 (uint8_t)((base->MULTI_ERR_ADDR_ECC0 & MECC_MULTI_ERR_ADDR_ECC0_MULTI_ERR_ECC_MASK) >>
0297 MECC_MULTI_ERR_ADDR_ECC0_MULTI_ERR_ECC_SHIFT);
0298 info->multiErrorAddress = (base->MULTI_ERR_ADDR_ECC0 & MECC_MULTI_ERR_ADDR_ECC0_MULTI_ERR_ADDR_MASK) >>
0299 MECC_MULTI_ERR_ADDR_ECC0_MULTI_ERR_ADDR_SHIFT;
0300 info->multiErrorDataLow = base->MULTI_ERR_DATA_LOW0;
0301 info->multiErrorDataHigh = base->MULTI_ERR_DATA_HIGH0;
0302 break;
0303
0304 case kMECC_OcramBank1:
0305 info->multiErrorEccCode =
0306 (uint8_t)((base->MULTI_ERR_ADDR_ECC1 & MECC_MULTI_ERR_ADDR_ECC1_MULTI_ERR_ECC_MASK) >>
0307 MECC_MULTI_ERR_ADDR_ECC1_MULTI_ERR_ECC_SHIFT);
0308 info->multiErrorAddress = (base->MULTI_ERR_ADDR_ECC1 & MECC_MULTI_ERR_ADDR_ECC1_MULTI_ERR_ADDR_MASK) >>
0309 MECC_MULTI_ERR_ADDR_ECC1_MULTI_ERR_ADDR_SHIFT;
0310 info->multiErrorDataLow = base->MULTI_ERR_DATA_LOW1;
0311 info->multiErrorDataHigh = base->MULTI_ERR_DATA_HIGH1;
0312 break;
0313
0314 case kMECC_OcramBank2:
0315 info->multiErrorEccCode =
0316 (uint8_t)((base->MULTI_ERR_ADDR_ECC2 & MECC_MULTI_ERR_ADDR_ECC2_MULTI_ERR_ECC_MASK) >>
0317 MECC_MULTI_ERR_ADDR_ECC2_MULTI_ERR_ECC_SHIFT);
0318 info->multiErrorAddress = (base->MULTI_ERR_ADDR_ECC2 & MECC_MULTI_ERR_ADDR_ECC2_MULTI_ERR_ADDR_MASK) >>
0319 MECC_MULTI_ERR_ADDR_ECC2_MULTI_ERR_ADDR_SHIFT;
0320 info->multiErrorDataLow = base->MULTI_ERR_DATA_LOW2;
0321 info->multiErrorDataHigh = base->MULTI_ERR_DATA_HIGH2;
0322 break;
0323
0324 case kMECC_OcramBank3:
0325 info->multiErrorEccCode =
0326 (uint8_t)((base->MULTI_ERR_ADDR_ECC3 & MECC_MULTI_ERR_ADDR_ECC3_MULTI_ERR_ECC_MASK) >>
0327 MECC_MULTI_ERR_ADDR_ECC3_MULTI_ERR_ECC_SHIFT);
0328 info->multiErrorAddress = (base->MULTI_ERR_ADDR_ECC3 & MECC_MULTI_ERR_ADDR_ECC3_MULTI_ERR_ADDR_MASK) >>
0329 MECC_MULTI_ERR_ADDR_ECC3_MULTI_ERR_ADDR_SHIFT;
0330 info->multiErrorDataLow = base->MULTI_ERR_DATA_LOW3;
0331 info->multiErrorDataHigh = base->MULTI_ERR_DATA_HIGH3;
0332 break;
0333
0334 default:
0335 status = kStatus_MECC_BankMiss;
0336 break;
0337 }
0338
0339 return status;
0340 }