File indexing completed on 2025-05-11 08:23:01
0001
0002
0003
0004
0005
0006
0007
0008 #include "fsl_semc.h"
0009
0010
0011
0012
0013
0014
0015 #ifndef FSL_COMPONENT_ID
0016 #define FSL_COMPONENT_ID "platform.drivers.semc"
0017 #endif
0018
0019
0020 #define SEMC_IPCOMMANDDATASIZEBYTEMAX (4U)
0021 #define SEMC_IPCOMMANDMAGICKEY (0xA55A)
0022 #if defined(FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT) && (FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT > 0x01U)
0023 #define SEMC_IOCR_PINMUXBITWIDTH (0x4UL)
0024 #else
0025 #define SEMC_IOCR_PINMUXBITWIDTH (0x3UL)
0026 #endif
0027 #define SEMC_IOCR_NAND_CE (4UL)
0028 #define SEMC_IOCR_NOR_CE (5UL)
0029 #define SEMC_IOCR_NOR_CE_A8 (2UL)
0030 #define SEMC_IOCR_PSRAM_CE (6UL)
0031 #if defined(SEMC_IOCR_PINMUXBITWIDTH) && (SEMC_IOCR_PINMUXBITWIDTH == 0x4UL)
0032 #define SEMC_IOCR_PSRAM_CE_A8 (6UL)
0033 #else
0034 #define SEMC_IOCR_PSRAM_CE_A8 (3UL)
0035 #endif
0036 #define SEMC_IOCR_DBI_CSX (7UL)
0037 #define SEMC_IOCR_DBI_CSX_A8 (4UL)
0038 #define SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE (24U)
0039 #define SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHMAX (28U)
0040 #define SEMC_BMCR0_TYPICAL_WQOS (5U)
0041 #define SEMC_BMCR0_TYPICAL_WAGE (8U)
0042 #define SEMC_BMCR0_TYPICAL_WSH (0x40U)
0043 #define SEMC_BMCR0_TYPICAL_WRWS (0x10U)
0044 #define SEMC_BMCR1_TYPICAL_WQOS (5U)
0045 #define SEMC_BMCR1_TYPICAL_WAGE (8U)
0046 #define SEMC_BMCR1_TYPICAL_WPH (0x60U)
0047 #define SEMC_BMCR1_TYPICAL_WBR (0x40U)
0048 #define SEMC_BMCR1_TYPICAL_WRWS (0x24U)
0049 #define SEMC_STARTADDRESS (0x80000000UL)
0050 #define SEMC_ENDADDRESS (0xDFFFFFFFUL)
0051 #define SEMC_BR_MEMSIZE_MIN (4U)
0052 #define SEMC_BR_MEMSIZE_OFFSET (2U)
0053 #define SEMC_BR_MEMSIZE_MAX (4UL * 1024UL * 1024UL)
0054 #define SEMC_SDRAM_MODESETCAL_OFFSET (4U)
0055 #define SEMC_BR_REG_NUM (9U)
0056 #define SEMC_BYTE_NUMBIT (8U)
0057
0058
0059
0060
0061
0062
0063
0064
0065 static uint32_t SEMC_GetInstance(SEMC_Type *base);
0066
0067
0068
0069
0070
0071
0072
0073
0074 static status_t SEMC_CovertMemorySize(uint32_t size_kbytes, uint8_t *sizeConverted);
0075
0076
0077
0078
0079
0080
0081
0082
0083 static uint8_t SEMC_ConvertTiming(uint32_t time_ns, uint32_t clkSrc_Hz);
0084
0085
0086
0087
0088
0089
0090
0091
0092 static status_t SEMC_ConfigureIPCommand(SEMC_Type *base, uint8_t size_bytes);
0093
0094
0095
0096
0097
0098
0099
0100 static status_t SEMC_IsIPCommandDone(SEMC_Type *base);
0101
0102
0103
0104
0105
0106 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0107
0108 static const clock_ip_name_t s_semcClock[FSL_FEATURE_SOC_SEMC_COUNT] = SEMC_CLOCKS;
0109 #if (defined(SEMC_EXSC_CLOCKS))
0110 static const clock_ip_name_t s_semcExtClock[FSL_FEATURE_SOC_SEMC_COUNT] = SEMC_EXSC_CLOCKS;
0111 #endif
0112 #endif
0113
0114
0115 static SEMC_Type *const s_semcBases[] = SEMC_BASE_PTRS;
0116
0117
0118
0119 static uint32_t SEMC_GetInstance(SEMC_Type *base)
0120 {
0121 uint32_t instance;
0122
0123
0124 for (instance = 0; instance < ARRAY_SIZE(s_semcBases); instance++)
0125 {
0126 if (s_semcBases[instance] == base)
0127 {
0128 break;
0129 }
0130 }
0131
0132 assert(instance < ARRAY_SIZE(s_semcBases));
0133
0134 return instance;
0135 }
0136
0137 static status_t SEMC_CovertMemorySize(uint32_t size_kbytes, uint8_t *sizeConverted)
0138 {
0139 assert(sizeConverted != NULL);
0140 uint32_t memsize;
0141 status_t status = kStatus_Success;
0142
0143 if ((size_kbytes < SEMC_BR_MEMSIZE_MIN) || (size_kbytes > SEMC_BR_MEMSIZE_MAX))
0144 {
0145 status = kStatus_SEMC_InvalidMemorySize;
0146 }
0147 else
0148 {
0149 *sizeConverted = 0U;
0150 memsize = size_kbytes / 8U;
0151 while (memsize != 0x00U)
0152 {
0153 memsize >>= 1U;
0154 (*sizeConverted)++;
0155 }
0156 }
0157
0158 return status;
0159 }
0160
0161 static uint8_t SEMC_ConvertTiming(uint32_t time_ns, uint32_t clkSrc_Hz)
0162 {
0163 assert(clkSrc_Hz != 0x00U);
0164
0165 uint8_t clockCycles = 0;
0166 uint32_t tClk_ps;
0167
0168 clkSrc_Hz /= 1000000U;
0169
0170 tClk_ps = 1000000U / clkSrc_Hz;
0171
0172 while (tClk_ps * clockCycles < time_ns * 1000U)
0173 {
0174 clockCycles++;
0175 }
0176
0177 return (clockCycles == 0x00U) ? clockCycles : (clockCycles - 0x01U);
0178 }
0179
0180 static status_t SEMC_ConfigureIPCommand(SEMC_Type *base, uint8_t size_bytes)
0181 {
0182 status_t status = kStatus_Success;
0183
0184 if ((size_bytes > SEMC_IPCOMMANDDATASIZEBYTEMAX) || (size_bytes == 0x00U))
0185 {
0186 status = kStatus_SEMC_InvalidIpcmdDataSize;
0187 }
0188 else
0189 {
0190
0191
0192
0193
0194
0195
0196 base->IPCR1 = SEMC_IPCR1_DATSZ(size_bytes);
0197
0198 base->IPCR2 = 0;
0199
0200 if (size_bytes < 4U)
0201 {
0202 base->IPCR2 |= SEMC_IPCR2_BM3_MASK;
0203 }
0204 if (size_bytes < 3U)
0205 {
0206 base->IPCR2 |= SEMC_IPCR2_BM2_MASK;
0207 }
0208 if (size_bytes < 2U)
0209 {
0210 base->IPCR2 |= SEMC_IPCR2_BM1_MASK;
0211 }
0212 }
0213
0214 return status;
0215 }
0216
0217 static status_t SEMC_IsIPCommandDone(SEMC_Type *base)
0218 {
0219 status_t status = kStatus_Success;
0220
0221
0222 while ((base->INTR & (uint32_t)SEMC_INTR_IPCMDDONE_MASK) == 0x00U)
0223 {
0224 };
0225
0226
0227 base->INTR |= SEMC_INTR_IPCMDDONE_MASK;
0228
0229
0230 if ((base->INTR & (uint32_t)SEMC_INTR_IPCMDERR_MASK) != 0x00U)
0231 {
0232 base->INTR |= SEMC_INTR_IPCMDERR_MASK;
0233 status = kStatus_SEMC_IpCommandExecutionError;
0234 }
0235
0236 return status;
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253 void SEMC_GetDefaultConfig(semc_config_t *config)
0254 {
0255 assert(config != NULL);
0256
0257
0258 (void)memset(config, 0, sizeof(*config));
0259
0260 config->queueWeight.queueaEnable = true;
0261 semc_queuea_weight_struct_t *queueaWeight = &(config->queueWeight.queueaWeight.queueaConfig);
0262 config->queueWeight.queuebEnable = true;
0263 semc_queueb_weight_struct_t *queuebWeight = &(config->queueWeight.queuebWeight.queuebConfig);
0264
0265
0266 config->dqsMode = kSEMC_Loopbackinternal;
0267 config->cmdTimeoutCycles = 0xFF;
0268 config->busTimeoutCycles = 0x1F;
0269
0270 queueaWeight->qos = SEMC_BMCR0_TYPICAL_WQOS;
0271 queueaWeight->aging = SEMC_BMCR0_TYPICAL_WAGE;
0272 queueaWeight->slaveHitSwith = SEMC_BMCR0_TYPICAL_WSH;
0273 queueaWeight->slaveHitNoswitch = SEMC_BMCR0_TYPICAL_WRWS;
0274 queuebWeight->qos = SEMC_BMCR1_TYPICAL_WQOS;
0275 queuebWeight->aging = SEMC_BMCR1_TYPICAL_WAGE;
0276 queuebWeight->slaveHitSwith = SEMC_BMCR1_TYPICAL_WRWS;
0277 queuebWeight->weightPagehit = SEMC_BMCR1_TYPICAL_WPH;
0278 queuebWeight->bankRotation = SEMC_BMCR1_TYPICAL_WBR;
0279 }
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289 void SEMC_Init(SEMC_Type *base, semc_config_t *configure)
0290 {
0291 assert(configure != NULL);
0292
0293 uint8_t index = 0;
0294
0295 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0296
0297 CLOCK_EnableClock(s_semcClock[SEMC_GetInstance(base)]);
0298 #if (defined(SEMC_EXSC_CLOCKS))
0299 CLOCK_EnableClock(s_semcExtClock[SEMC_GetInstance(base)]);
0300 #endif
0301 #endif
0302
0303
0304 for (index = 0; index < SEMC_BR_REG_NUM; index++)
0305 {
0306 base->BR[index] = 0;
0307 }
0308
0309
0310 base->MCR = SEMC_MCR_SWRST_MASK;
0311 while ((base->MCR & (uint32_t)SEMC_MCR_SWRST_MASK) != 0x00U)
0312 {
0313 }
0314
0315
0316 base->MCR |= SEMC_MCR_MDIS_MASK | SEMC_MCR_BTO(configure->busTimeoutCycles) |
0317 SEMC_MCR_CTO(configure->cmdTimeoutCycles) | SEMC_MCR_DQSMD(configure->dqsMode);
0318
0319 if (configure->queueWeight.queueaEnable == true)
0320 {
0321
0322 base->BMCR0 = (uint32_t)(configure->queueWeight.queueaWeight.queueaValue);
0323 }
0324 else
0325 {
0326 base->BMCR0 = 0x00U;
0327 }
0328
0329 if (configure->queueWeight.queuebEnable == true)
0330 {
0331
0332 base->BMCR1 = (uint32_t)(configure->queueWeight.queuebWeight.queuebValue);
0333 }
0334 else
0335 {
0336 base->BMCR1 = 0x00U;
0337 }
0338
0339
0340 base->MCR &= ~SEMC_MCR_MDIS_MASK;
0341 }
0342
0343
0344
0345
0346
0347
0348
0349
0350 void SEMC_Deinit(SEMC_Type *base)
0351 {
0352
0353 while ((base->STS0 & (uint32_t)SEMC_STS0_IDLE_MASK) == 0x00U)
0354 {
0355 ;
0356 }
0357
0358 base->MCR |= SEMC_MCR_MDIS_MASK | SEMC_MCR_SWRST_MASK;
0359
0360 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0361
0362 CLOCK_DisableClock(s_semcClock[SEMC_GetInstance(base)]);
0363 #if (defined(SEMC_EXSC_CLOCKS))
0364 CLOCK_DisableClock(s_semcExtClock[SEMC_GetInstance(base)]);
0365 #endif
0366 #endif
0367 }
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377 status_t SEMC_ConfigureSDRAM(SEMC_Type *base, semc_sdram_cs_t cs, semc_sdram_config_t *config, uint32_t clkSrc_Hz)
0378 {
0379 assert(config != NULL);
0380 assert(clkSrc_Hz > 0x00U);
0381 assert(config->refreshBurstLen > 0x00U);
0382
0383 uint8_t memsize;
0384 status_t result = kStatus_Success;
0385 uint16_t prescale = (uint16_t)(config->tPrescalePeriod_Ns / 16U / (1000000000U / clkSrc_Hz));
0386 uint32_t refresh;
0387 uint32_t urgentRef;
0388 uint32_t idle;
0389 uint32_t mode;
0390 uint32_t timing;
0391
0392 if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS))
0393 {
0394 return kStatus_SEMC_InvalidBaseAddress;
0395 }
0396
0397 if (config->csxPinMux == kSEMC_MUXA8)
0398 {
0399 return kStatus_SEMC_InvalidSwPinmuxSelection;
0400 }
0401
0402 if (prescale > 256U)
0403 {
0404 return kStatus_SEMC_InvalidTimerSetting;
0405 }
0406
0407 refresh = config->refreshPeriod_nsPerRow / config->tPrescalePeriod_Ns;
0408 urgentRef = config->refreshUrgThreshold / config->tPrescalePeriod_Ns;
0409 idle = config->tIdleTimeout_Ns / config->tPrescalePeriod_Ns;
0410
0411 uint32_t iocReg = base->IOCR & (~(SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->csxPinMux));
0412
0413
0414 result = SEMC_CovertMemorySize(config->memsize_kbytes, &memsize);
0415 if (result != kStatus_Success)
0416 {
0417 return result;
0418 }
0419
0420 base->BR[cs] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK;
0421
0422 #if defined(FSL_FEATURE_SEMC_SDRAM_SUPPORT_COLUMN_ADDRESS_8BIT) && (FSL_FEATURE_SEMC_SDRAM_SUPPORT_COLUMN_ADDRESS_8BIT)
0423 if (kSEMC_SdramColunm_8bit == config->columnAddrBitNum)
0424 {
0425 base->SDRAMCR0 = SEMC_SDRAMCR0_PS(config->portSize) | SEMC_SDRAMCR0_BL(config->burstLen) |
0426 SEMC_SDRAMCR0_COL8(true) | SEMC_SDRAMCR0_CL(config->casLatency);
0427 }
0428 else
0429 #endif
0430 {
0431 base->SDRAMCR0 = SEMC_SDRAMCR0_PS(config->portSize) | SEMC_SDRAMCR0_BL(config->burstLen) |
0432 SEMC_SDRAMCR0_COL(config->columnAddrBitNum) | SEMC_SDRAMCR0_CL(config->casLatency);
0433 }
0434
0435
0436 if (cs != kSEMC_SDRAM_CS0)
0437 {
0438 base->IOCR = iocReg | ((uint32_t)cs << (uint32_t)config->csxPinMux);
0439 }
0440
0441 base->IOCR &= ~SEMC_IOCR_MUX_A8_MASK;
0442
0443 #if defined(FSL_FEATURE_SEMC_HAS_DELAY_CHAIN_CONTROL) && (FSL_FEATURE_SEMC_HAS_DELAY_CHAIN_CONTROL)
0444 uint32_t tempDelayChain = base->DCCR;
0445
0446 tempDelayChain &= ~(SEMC_DCCR_SDRAMVAL_MASK | SEMC_DCCR_SDRAMEN_MASK);
0447
0448 base->DCCR = tempDelayChain | SEMC_DCCR_SDRAMVAL((uint32_t)config->delayChain - 0x01U) | SEMC_DCCR_SDRAMEN_MASK;
0449 #endif
0450
0451 timing = SEMC_SDRAMCR1_PRE2ACT(SEMC_ConvertTiming(config->tPrecharge2Act_Ns, clkSrc_Hz));
0452 timing |= SEMC_SDRAMCR1_ACT2RW(SEMC_ConvertTiming(config->tAct2ReadWrite_Ns, clkSrc_Hz));
0453 timing |= SEMC_SDRAMCR1_RFRC(SEMC_ConvertTiming(config->tRefreshRecovery_Ns, clkSrc_Hz));
0454 timing |= SEMC_SDRAMCR1_WRC(SEMC_ConvertTiming(config->tWriteRecovery_Ns, clkSrc_Hz));
0455 timing |= SEMC_SDRAMCR1_CKEOFF(SEMC_ConvertTiming(config->tCkeOff_Ns, clkSrc_Hz));
0456 timing |= SEMC_SDRAMCR1_ACT2PRE(SEMC_ConvertTiming(config->tAct2Prechage_Ns, clkSrc_Hz));
0457
0458 base->SDRAMCR1 = timing;
0459
0460 timing = SEMC_SDRAMCR2_SRRC(SEMC_ConvertTiming(config->tSelfRefRecovery_Ns, clkSrc_Hz));
0461 timing |= SEMC_SDRAMCR2_REF2REF(SEMC_ConvertTiming(config->tRefresh2Refresh_Ns, clkSrc_Hz));
0462 timing |= SEMC_SDRAMCR2_ACT2ACT(SEMC_ConvertTiming(config->tAct2Act_Ns, clkSrc_Hz)) | SEMC_SDRAMCR2_ITO(idle);
0463
0464 base->SDRAMCR2 = timing;
0465
0466
0467 base->SDRAMCR3 = SEMC_SDRAMCR3_REBL((uint32_t)config->refreshBurstLen - 1UL) |
0468
0469 SEMC_SDRAMCR3_PRESCALE(prescale) | SEMC_SDRAMCR3_RT(refresh - 1UL) | SEMC_SDRAMCR3_UT(urgentRef);
0470
0471 SEMC->IPCR1 = 0x2U;
0472 SEMC->IPCR2 = 0U;
0473
0474 result =
0475 SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, (uint32_t)kSEMC_SDRAMCM_Prechargeall, 0, NULL);
0476 if (result != kStatus_Success)
0477 {
0478 return result;
0479 }
0480 result =
0481 SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, (uint32_t)kSEMC_SDRAMCM_AutoRefresh, 0, NULL);
0482 if (result != kStatus_Success)
0483 {
0484 return result;
0485 }
0486 result =
0487 SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, (uint32_t)kSEMC_SDRAMCM_AutoRefresh, 0, NULL);
0488 if (result != kStatus_Success)
0489 {
0490 return result;
0491 }
0492
0493 mode = (uint32_t)config->burstLen | (((uint32_t)config->casLatency) << SEMC_SDRAM_MODESETCAL_OFFSET);
0494 result =
0495 SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, (uint32_t)kSEMC_SDRAMCM_Modeset, mode, NULL);
0496 if (result != kStatus_Success)
0497 {
0498 return result;
0499 }
0500
0501 base->SDRAMCR3 |= SEMC_SDRAMCR3_REN_MASK;
0502
0503 return kStatus_Success;
0504 }
0505
0506
0507
0508
0509
0510
0511
0512
0513 status_t SEMC_ConfigureNAND(SEMC_Type *base, semc_nand_config_t *config, uint32_t clkSrc_Hz)
0514 {
0515 assert(config != NULL);
0516 assert(config->timingConfig != NULL);
0517
0518 uint8_t memsize;
0519 status_t result;
0520 uint32_t timing;
0521
0522 if ((config->axiAddress < SEMC_STARTADDRESS) || (config->axiAddress > SEMC_ENDADDRESS))
0523 {
0524 return kStatus_SEMC_InvalidBaseAddress;
0525 }
0526
0527 if (config->cePinMux == kSEMC_MUXRDY)
0528 {
0529 return kStatus_SEMC_InvalidSwPinmuxSelection;
0530 }
0531
0532
0533 base->MCR |= SEMC_MCR_MDIS_MASK;
0534
0535 uint32_t iocReg =
0536 base->IOCR & (~((SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->cePinMux) | SEMC_IOCR_MUX_RDY_MASK));
0537
0538
0539 if (config->rdyactivePolarity == kSEMC_RdyActivehigh)
0540 {
0541 base->MCR |= SEMC_MCR_WPOL1_MASK;
0542 }
0543 else
0544 {
0545 base->MCR &= ~SEMC_MCR_WPOL1_MASK;
0546 }
0547 result = SEMC_CovertMemorySize(config->axiMemsize_kbytes, &memsize);
0548 if (result != kStatus_Success)
0549 {
0550 return result;
0551 }
0552 base->BR[4] = (config->axiAddress & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK;
0553
0554 result = SEMC_CovertMemorySize(config->ipgMemsize_kbytes, &memsize);
0555 if (result != kStatus_Success)
0556 {
0557 return result;
0558 }
0559 base->BR[8] = (config->ipgAddress & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK;
0560
0561
0562 if ((uint32_t)config->cePinMux != 0x00U)
0563 {
0564 base->IOCR = iocReg | (SEMC_IOCR_NAND_CE << (uint32_t)config->cePinMux);
0565 }
0566 else
0567 {
0568 base->IOCR = iocReg | (1UL << (uint32_t)config->cePinMux);
0569 }
0570
0571 base->NANDCR0 = SEMC_NANDCR0_PS(config->portSize) | SEMC_NANDCR0_BL(config->burstLen) |
0572 SEMC_NANDCR0_EDO(config->edoModeEnabled) | SEMC_NANDCR0_COL(config->columnAddrBitNum);
0573
0574 timing = SEMC_NANDCR1_CES(SEMC_ConvertTiming(config->timingConfig->tCeSetup_Ns, clkSrc_Hz));
0575 timing |= SEMC_NANDCR1_CEH(SEMC_ConvertTiming(config->timingConfig->tCeHold_Ns, clkSrc_Hz));
0576 timing |= SEMC_NANDCR1_WEL(SEMC_ConvertTiming(config->timingConfig->tWeLow_Ns, clkSrc_Hz));
0577 timing |= SEMC_NANDCR1_WEH(SEMC_ConvertTiming(config->timingConfig->tWeHigh_Ns, clkSrc_Hz));
0578 timing |= SEMC_NANDCR1_REL(SEMC_ConvertTiming(config->timingConfig->tReLow_Ns, clkSrc_Hz));
0579 timing |= SEMC_NANDCR1_REH(SEMC_ConvertTiming(config->timingConfig->tReHigh_Ns, clkSrc_Hz));
0580 timing |= SEMC_NANDCR1_TA(SEMC_ConvertTiming(config->timingConfig->tTurnAround_Ns, clkSrc_Hz));
0581 timing |= SEMC_NANDCR1_CEITV(SEMC_ConvertTiming(config->timingConfig->tCeInterval_Ns, clkSrc_Hz));
0582
0583 base->NANDCR1 = timing;
0584
0585 timing = SEMC_NANDCR2_TWHR(SEMC_ConvertTiming(config->timingConfig->tWehigh2Relow_Ns, clkSrc_Hz));
0586 timing |= SEMC_NANDCR2_TRHW(SEMC_ConvertTiming(config->timingConfig->tRehigh2Welow_Ns, clkSrc_Hz));
0587 timing |= SEMC_NANDCR2_TADL(SEMC_ConvertTiming(config->timingConfig->tAle2WriteStart_Ns, clkSrc_Hz));
0588 timing |= SEMC_NANDCR2_TRR(SEMC_ConvertTiming(config->timingConfig->tReady2Relow_Ns, clkSrc_Hz));
0589 timing |= SEMC_NANDCR2_TWB(SEMC_ConvertTiming(config->timingConfig->tWehigh2Busy_Ns, clkSrc_Hz));
0590
0591
0592 base->NANDCR2 = timing;
0593
0594
0595 base->NANDCR3 = (uint32_t)config->arrayAddrOption;
0596
0597
0598 base->MCR &= ~SEMC_MCR_MDIS_MASK;
0599
0600 return kStatus_Success;
0601 }
0602
0603
0604
0605
0606
0607
0608
0609
0610 status_t SEMC_ConfigureNOR(SEMC_Type *base, semc_nor_config_t *config, uint32_t clkSrc_Hz)
0611 {
0612 assert(config != NULL);
0613
0614 uint8_t memsize;
0615 status_t result;
0616 uint32_t timing;
0617
0618 if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS))
0619 {
0620 return kStatus_SEMC_InvalidBaseAddress;
0621 }
0622
0623 uint32_t iocReg = base->IOCR & (~(SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->cePinMux));
0624 uint32_t muxCe = (config->cePinMux == kSEMC_MUXRDY) ?
0625 (SEMC_IOCR_NOR_CE - 1U) :
0626 ((config->cePinMux == kSEMC_MUXA8) ? SEMC_IOCR_NOR_CE_A8 : SEMC_IOCR_NOR_CE);
0627
0628
0629 base->IOCR = iocReg | (muxCe << (uint32_t)config->cePinMux);
0630
0631 if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE)
0632 {
0633 if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 1U))
0634 {
0635
0636 base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX0_MASK;
0637 if (config->cePinMux == kSEMC_MUXCSX0)
0638 {
0639 return kStatus_SEMC_InvalidSwPinmuxSelection;
0640 }
0641 }
0642 if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 2U))
0643 {
0644
0645 base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX1_MASK;
0646 if (config->cePinMux == kSEMC_MUXCSX1)
0647 {
0648 return kStatus_SEMC_InvalidSwPinmuxSelection;
0649 }
0650 }
0651 if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 3U))
0652 {
0653
0654 base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX2_MASK;
0655 if (config->cePinMux == kSEMC_MUXCSX2)
0656 {
0657 return kStatus_SEMC_InvalidSwPinmuxSelection;
0658 }
0659 }
0660 if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 4U))
0661 {
0662 if (config->addr27 == kSEMC_NORA27_MUXCSX3)
0663 {
0664
0665 base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX3_MASK;
0666 }
0667 else if (config->addr27 == kSEMC_NORA27_MUXRDY)
0668 {
0669 base->IOCR |= SEMC_IOCR_MUX_RDY_MASK;
0670 }
0671 else
0672 {
0673 return kStatus_SEMC_InvalidSwPinmuxSelection;
0674 }
0675 if (config->cePinMux == kSEMC_MUXCSX3)
0676 {
0677 return kStatus_SEMC_InvalidSwPinmuxSelection;
0678 }
0679 }
0680 if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHMAX)
0681 {
0682 return kStatus_SEMC_InvalidAddressPortWidth;
0683 }
0684 }
0685
0686
0687 if (config->rdyactivePolarity == kSEMC_RdyActivehigh)
0688 {
0689 base->MCR |= SEMC_MCR_WPOL0_MASK;
0690 }
0691 else
0692 {
0693 base->MCR &= ~SEMC_MCR_WPOL0_MASK;
0694 }
0695 result = SEMC_CovertMemorySize(config->memsize_kbytes, &memsize);
0696 if (result != kStatus_Success)
0697 {
0698 return result;
0699 }
0700 base->BR[5] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK;
0701 base->NORCR0 = SEMC_NORCR0_PS(config->portSize) | SEMC_NORCR0_BL(config->burstLen) |
0702 SEMC_NORCR0_AM(config->addrMode) | SEMC_NORCR0_ADVP(config->advActivePolarity) |
0703 SEMC_NORCR0_COL(config->columnAddrBitNum);
0704
0705 #if defined(FSL_FEATURE_SEMC_HAS_DELAY_CHAIN_CONTROL) && (FSL_FEATURE_SEMC_HAS_DELAY_CHAIN_CONTROL)
0706 uint32_t tempDelayChain = base->DCCR;
0707
0708 tempDelayChain &= ~(SEMC_DCCR_NORVAL_MASK | SEMC_DCCR_NOREN_MASK);
0709
0710 base->DCCR = tempDelayChain | SEMC_DCCR_NORVAL((uint32_t)config->delayChain - 0x01U) | SEMC_DCCR_NOREN_MASK;
0711 #endif
0712
0713 timing = SEMC_NORCR1_CES(SEMC_ConvertTiming(config->tCeSetup_Ns, clkSrc_Hz));
0714 timing |= SEMC_NORCR1_CEH(SEMC_ConvertTiming(config->tCeHold_Ns, clkSrc_Hz));
0715 timing |= SEMC_NORCR1_AS(SEMC_ConvertTiming(config->tAddrSetup_Ns, clkSrc_Hz));
0716 timing |= SEMC_NORCR1_AH(SEMC_ConvertTiming(config->tAddrHold_Ns, clkSrc_Hz));
0717 timing |= SEMC_NORCR1_WEL(SEMC_ConvertTiming(config->tWeLow_Ns, clkSrc_Hz));
0718 timing |= SEMC_NORCR1_WEH(SEMC_ConvertTiming(config->tWeHigh_Ns, clkSrc_Hz));
0719 timing |= SEMC_NORCR1_REL(SEMC_ConvertTiming(config->tReLow_Ns, clkSrc_Hz));
0720 timing |= SEMC_NORCR1_REH(SEMC_ConvertTiming(config->tReHigh_Ns, clkSrc_Hz));
0721
0722
0723 base->NORCR1 = timing;
0724
0725 timing = SEMC_NORCR2_CEITV(SEMC_ConvertTiming(config->tCeInterval_Ns, clkSrc_Hz));
0726 #if defined(FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME)
0727 timing |= SEMC_NORCR2_WDS(SEMC_ConvertTiming(config->tWriteSetup_Ns, clkSrc_Hz));
0728 #endif
0729 #if defined(FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME)
0730 timing |= SEMC_NORCR2_WDH(SEMC_ConvertTiming(config->tWriteHold_Ns, clkSrc_Hz));
0731 #endif
0732 timing |= SEMC_NORCR2_TA(SEMC_ConvertTiming(config->tTurnAround_Ns, clkSrc_Hz));
0733 timing |= SEMC_NORCR2_AWDH((uint32_t)SEMC_ConvertTiming(config->tAddr2WriteHold_Ns, clkSrc_Hz) + 0x01UL);
0734 #if defined(FSL_FEATURE_SEMC_HAS_NOR_LC_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_LC_TIME)
0735 timing |= SEMC_NORCR2_LC(config->latencyCount);
0736 #endif
0737 #if defined(FSL_FEATURE_SEMC_HAS_NOR_RD_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_RD_TIME)
0738 timing |= SEMC_NORCR2_RD((uint32_t)config->readCycle - 0x01UL);
0739 #endif
0740
0741
0742 base->NORCR2 = timing;
0743
0744 return SEMC_ConfigureIPCommand(base, ((uint8_t)config->portSize + 1U));
0745 }
0746
0747
0748
0749
0750
0751
0752
0753
0754 status_t SEMC_ConfigureSRAM(SEMC_Type *base, semc_sram_config_t *config, uint32_t clkSrc_Hz)
0755 {
0756 return SEMC_ConfigureSRAMWithChipSelection(base, kSEMC_SRAM_CS0, config, clkSrc_Hz);
0757 }
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767 status_t SEMC_ConfigureSRAMWithChipSelection(SEMC_Type *base,
0768 semc_sram_cs_t cs,
0769 semc_sram_config_t *config,
0770 uint32_t clkSrc_Hz)
0771 {
0772 assert(config != NULL);
0773
0774 uint32_t tempBRVal;
0775 uint32_t timing;
0776 uint8_t memsize;
0777 status_t result = kStatus_Success;
0778
0779 if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS))
0780 {
0781 return kStatus_SEMC_InvalidBaseAddress;
0782 }
0783
0784 uint32_t iocReg = base->IOCR & (~(SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->cePinMux));
0785
0786 uint32_t muxCe = (config->cePinMux == kSEMC_MUXRDY) ?
0787 (SEMC_IOCR_PSRAM_CE - 1U) :
0788 ((config->cePinMux == kSEMC_MUXA8) ? SEMC_IOCR_PSRAM_CE_A8 : SEMC_IOCR_PSRAM_CE);
0789
0790
0791 base->IOCR = iocReg | (muxCe << (uint32_t)config->cePinMux);
0792
0793 if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE)
0794 {
0795 if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 1U))
0796 {
0797
0798 base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX0_MASK;
0799 if (config->cePinMux == kSEMC_MUXCSX0)
0800 {
0801 return kStatus_SEMC_InvalidSwPinmuxSelection;
0802 }
0803 }
0804 if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 2U))
0805 {
0806
0807 base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX1_MASK;
0808 if (config->cePinMux == kSEMC_MUXCSX1)
0809 {
0810 return kStatus_SEMC_InvalidSwPinmuxSelection;
0811 }
0812 }
0813 if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 3U))
0814 {
0815
0816 base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX2_MASK;
0817 if (config->cePinMux == kSEMC_MUXCSX2)
0818 {
0819 return kStatus_SEMC_InvalidSwPinmuxSelection;
0820 }
0821 }
0822 if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 4U))
0823 {
0824 if (config->addr27 == kSEMC_NORA27_MUXCSX3)
0825 {
0826
0827 base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX3_MASK;
0828 }
0829 else if (config->addr27 == kSEMC_NORA27_MUXRDY)
0830 {
0831 base->IOCR |= SEMC_IOCR_MUX_RDY_MASK;
0832 }
0833 else
0834 {
0835 return kStatus_SEMC_InvalidSwPinmuxSelection;
0836 }
0837
0838 if (config->cePinMux == kSEMC_MUXCSX3)
0839 {
0840 return kStatus_SEMC_InvalidSwPinmuxSelection;
0841 }
0842 }
0843 if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHMAX)
0844 {
0845 return kStatus_SEMC_InvalidAddressPortWidth;
0846 }
0847 }
0848
0849 result = SEMC_CovertMemorySize(config->memsize_kbytes, &memsize);
0850 if (result != kStatus_Success)
0851 {
0852 return result;
0853 }
0854
0855 tempBRVal = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK;
0856
0857 uint32_t tempCtrlVal;
0858
0859 switch (cs)
0860 {
0861 case kSEMC_SRAM_CS0:
0862 base->BR[6] = tempBRVal;
0863 break;
0864 #if defined(FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT) && (FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT > 0x01U)
0865 case kSEMC_SRAM_CS1:
0866 base->BR9 = tempBRVal;
0867 break;
0868 case kSEMC_SRAM_CS2:
0869 base->BR10 = tempBRVal;
0870 break;
0871 case kSEMC_SRAM_CS3:
0872 base->BR11 = tempBRVal;
0873 break;
0874 #endif
0875 default:
0876 assert(NULL);
0877 break;
0878 }
0879
0880
0881 if (kSEMC_SRAM_CS0 == cs)
0882 {
0883 #if defined(FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT) && (FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT > 0x01U)
0884
0885 if (kSEMC_AsyncMode == config->syncMode)
0886 {
0887 tempCtrlVal = SEMC_SRAMCR0_PS(config->portSize) |
0888 #if defined(SEMC_SRAMCR4_SYNCEN_MASK) && (SEMC_SRAMCR4_SYNCEN_MASK)
0889 SEMC_SRAMCR4_SYNCEN(config->syncMode) |
0890 #endif
0891 #if defined(SEMC_SRAMCR0_WAITEN_MASK) && (SEMC_SRAMCR0_WAITEN_MASK)
0892 SEMC_SRAMCR0_WAITEN(config->waitEnable) |
0893 #endif
0894 #if defined(SEMC_SRAMCR0_WAITSP_MASK) && (SEMC_SRAMCR0_WAITSP_MASK)
0895 SEMC_SRAMCR0_WAITSP(config->waitSample) |
0896 #endif
0897 SEMC_SRAMCR0_BL(config->burstLen) | SEMC_SRAMCR0_AM(config->addrMode) |
0898 SEMC_SRAMCR0_ADVP(config->advActivePolarity) |
0899 #if defined(SEMC_SRAMCR4_ADVH_MASK) && (SEMC_SRAMCR4_ADVH_MASK)
0900 SEMC_SRAMCR4_ADVH(config->advLevelCtrl) |
0901 #endif
0902 SEMC_SRAMCR0_COL_MASK;
0903 }
0904 else
0905 #endif
0906 {
0907 tempCtrlVal = SEMC_SRAMCR0_PS(config->portSize) |
0908 #if defined(SEMC_SRAMCR4_SYNCEN_MASK) && (SEMC_SRAMCR4_SYNCEN_MASK)
0909 SEMC_SRAMCR4_SYNCEN(config->syncMode) |
0910 #endif
0911 SEMC_SRAMCR0_BL(config->burstLen) | SEMC_SRAMCR0_AM(config->addrMode) |
0912 SEMC_SRAMCR0_ADVP(config->advActivePolarity) |
0913 #if defined(SEMC_SRAMCR4_ADVH_MASK) && (SEMC_SRAMCR4_ADVH_MASK)
0914 SEMC_SRAMCR4_ADVH(config->advLevelCtrl) |
0915 #endif
0916 SEMC_SRAMCR0_COL_MASK;
0917 }
0918
0919 base->SRAMCR0 = tempCtrlVal;
0920 }
0921 #if defined(FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT) && (FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT > 0x01U)
0922
0923 else
0924 {
0925
0926 if (kSEMC_AsyncMode == config->syncMode)
0927 {
0928 tempCtrlVal = SEMC_SRAMCR4_PS(config->portSize) | SEMC_SRAMCR4_SYNCEN(config->syncMode) |
0929 SEMC_SRAMCR4_WAITEN(config->waitEnable) | SEMC_SRAMCR4_WAITSP(config->waitSample) |
0930 SEMC_SRAMCR4_BL(config->burstLen) | SEMC_SRAMCR4_AM(config->addrMode) |
0931 SEMC_SRAMCR4_ADVP(config->advActivePolarity) | SEMC_SRAMCR4_ADVH(config->advLevelCtrl) |
0932 SEMC_SRAMCR4_COL_MASK;
0933 }
0934 else
0935 {
0936 tempCtrlVal = SEMC_SRAMCR4_PS(config->portSize) | SEMC_SRAMCR4_SYNCEN(config->syncMode) |
0937 SEMC_SRAMCR4_BL(config->burstLen) | SEMC_SRAMCR4_AM(config->addrMode) |
0938 SEMC_SRAMCR4_ADVP(config->advActivePolarity) | SEMC_SRAMCR4_ADVH(config->advLevelCtrl) |
0939 SEMC_SRAMCR4_COL_MASK;
0940 }
0941
0942 base->SRAMCR4 = tempCtrlVal;
0943 }
0944 #endif
0945
0946 #if defined(FSL_FEATURE_SEMC_HAS_DELAY_CHAIN_CONTROL) && (FSL_FEATURE_SEMC_HAS_DELAY_CHAIN_CONTROL)
0947 uint32_t tempDelayChain = base->DCCR;
0948
0949
0950 switch (cs)
0951 {
0952 case kSEMC_SRAM_CS0:
0953 tempDelayChain &= ~(SEMC_DCCR_SRAM0VAL_MASK | SEMC_DCCR_SRAM0EN_MASK);
0954 base->DCCR =
0955 tempDelayChain | SEMC_DCCR_SRAM0VAL((uint32_t)config->delayChain - 0x01U) | SEMC_DCCR_SRAM0EN_MASK;
0956 break;
0957 #if defined(FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT) && (FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT > 0x01U)
0958 case kSEMC_SRAM_CS1:
0959 SUPPRESS_FALL_THROUGH_WARNING();
0960 case kSEMC_SRAM_CS2:
0961 SUPPRESS_FALL_THROUGH_WARNING();
0962 case kSEMC_SRAM_CS3:
0963 tempDelayChain &= ~(SEMC_DCCR_SRAMXVAL_MASK | SEMC_DCCR_SRAMXEN_MASK);
0964 base->DCCR =
0965 tempDelayChain | SEMC_DCCR_SRAMXVAL((uint32_t)config->delayChain - 0x01U) | SEMC_DCCR_SRAMXEN_MASK;
0966 break;
0967 #endif
0968 default:
0969 assert(NULL);
0970 break;
0971 }
0972 #endif
0973
0974 if (kSEMC_SRAM_CS0 == cs)
0975 {
0976 timing = SEMC_SRAMCR1_CES(SEMC_ConvertTiming(config->tCeSetup_Ns, clkSrc_Hz));
0977 timing |= SEMC_SRAMCR1_CEH(SEMC_ConvertTiming(config->tCeHold_Ns, clkSrc_Hz));
0978 timing |= SEMC_SRAMCR1_AS(SEMC_ConvertTiming(config->tAddrSetup_Ns, clkSrc_Hz));
0979 timing |= SEMC_SRAMCR1_AH(SEMC_ConvertTiming(config->tAddrHold_Ns, clkSrc_Hz));
0980 timing |= SEMC_SRAMCR1_WEL(SEMC_ConvertTiming(config->tWeLow_Ns, clkSrc_Hz));
0981 timing |= SEMC_SRAMCR1_WEH(SEMC_ConvertTiming(config->tWeHigh_Ns, clkSrc_Hz));
0982 timing |= SEMC_SRAMCR1_REL(SEMC_ConvertTiming(config->tReLow_Ns, clkSrc_Hz));
0983 timing |= SEMC_SRAMCR1_REH(SEMC_ConvertTiming(config->tReHigh_Ns, clkSrc_Hz));
0984
0985
0986 base->SRAMCR1 = timing;
0987
0988 timing = 0x00U;
0989 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_WDS_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_WDS_TIME)
0990 timing |= SEMC_SRAMCR2_WDS(SEMC_ConvertTiming(config->tWriteSetup_Ns, clkSrc_Hz));
0991 #endif
0992 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_WDH_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_WDH_TIME)
0993 timing |= SEMC_SRAMCR2_WDH((uint32_t)SEMC_ConvertTiming(config->tWriteHold_Ns, clkSrc_Hz) + 1UL);
0994 #endif
0995 timing |= SEMC_SRAMCR2_TA(SEMC_ConvertTiming(config->tTurnAround_Ns, clkSrc_Hz));
0996 timing |= SEMC_SRAMCR2_AWDH(SEMC_ConvertTiming(config->tAddr2WriteHold_Ns, clkSrc_Hz));
0997 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_LC_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_LC_TIME)
0998 timing |= SEMC_SRAMCR2_LC(config->latencyCount);
0999 #endif
1000 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_RD_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_RD_TIME)
1001 timing |= SEMC_SRAMCR2_RD((uint32_t)config->readCycle - 1UL);
1002 #endif
1003 timing |= SEMC_SRAMCR2_CEITV(SEMC_ConvertTiming(config->tCeInterval_Ns, clkSrc_Hz));
1004 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_RDH_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_RDH_TIME)
1005 timing |= SEMC_SRAMCR2_RDH((uint32_t)SEMC_ConvertTiming(config->readHoldTime_Ns, clkSrc_Hz) + 0x01U);
1006 #endif
1007
1008
1009 base->SRAMCR2 = timing;
1010 }
1011 #if defined(FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT) && (FSL_FEATURE_SEMC_SUPPORT_SRAM_COUNT > 0x01U)
1012 else
1013 {
1014 timing = SEMC_SRAMCR5_CES(SEMC_ConvertTiming(config->tCeSetup_Ns, clkSrc_Hz));
1015 timing |= SEMC_SRAMCR5_CEH(SEMC_ConvertTiming(config->tCeHold_Ns, clkSrc_Hz));
1016 timing |= SEMC_SRAMCR5_AS(SEMC_ConvertTiming(config->tAddrSetup_Ns, clkSrc_Hz));
1017 timing |= SEMC_SRAMCR5_AH(SEMC_ConvertTiming(config->tAddrHold_Ns, clkSrc_Hz));
1018 timing |= SEMC_SRAMCR5_WEL(SEMC_ConvertTiming(config->tWeLow_Ns, clkSrc_Hz));
1019 timing |= SEMC_SRAMCR5_WEH(SEMC_ConvertTiming(config->tWeHigh_Ns, clkSrc_Hz));
1020 timing |= SEMC_SRAMCR5_REL(SEMC_ConvertTiming(config->tReLow_Ns, clkSrc_Hz));
1021 timing |= SEMC_SRAMCR5_REH(SEMC_ConvertTiming(config->tReHigh_Ns, clkSrc_Hz));
1022
1023
1024 base->SRAMCR5 = timing;
1025
1026 timing = 0x00U;
1027 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_WDS_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_WDS_TIME)
1028 timing = SEMC_SRAMCR6_WDS(SEMC_ConvertTiming(config->tWriteSetup_Ns, clkSrc_Hz));
1029 #endif
1030 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_WDH_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_WDH_TIME)
1031 timing |= SEMC_SRAMCR6_WDH((uint32_t)SEMC_ConvertTiming(config->tWriteHold_Ns, clkSrc_Hz) + 1UL);
1032 #endif
1033 timing |= SEMC_SRAMCR6_TA(SEMC_ConvertTiming(config->tTurnAround_Ns, clkSrc_Hz));
1034 timing |= SEMC_SRAMCR6_AWDH(SEMC_ConvertTiming(config->tAddr2WriteHold_Ns, clkSrc_Hz));
1035 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_LC_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_LC_TIME)
1036 timing |= SEMC_SRAMCR6_LC(config->latencyCount);
1037 #endif
1038 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_RD_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_RD_TIME)
1039 timing |= SEMC_SRAMCR6_RD((uint32_t)config->readCycle - 1UL);
1040 #endif
1041 timing |= SEMC_SRAMCR6_CEITV(SEMC_ConvertTiming(config->tCeInterval_Ns, clkSrc_Hz));
1042 #if defined(FSL_FEATURE_SEMC_HAS_SRAM_RDH_TIME) && (FSL_FEATURE_SEMC_HAS_SRAM_RDH_TIME)
1043 timing |= SEMC_SRAMCR6_RDH((uint32_t)SEMC_ConvertTiming(config->readHoldTime_Ns, clkSrc_Hz) + 0x01U);
1044 #endif
1045
1046
1047 base->SRAMCR6 = timing;
1048 }
1049 #endif
1050
1051 return result;
1052 }
1053
1054
1055
1056
1057
1058
1059
1060
1061 status_t SEMC_ConfigureDBI(SEMC_Type *base, semc_dbi_config_t *config, uint32_t clkSrc_Hz)
1062 {
1063 assert(config != NULL);
1064
1065 uint8_t memsize;
1066 status_t result;
1067 uint32_t timing;
1068
1069 if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS))
1070 {
1071 return kStatus_SEMC_InvalidBaseAddress;
1072 }
1073
1074 uint32_t iocReg = base->IOCR & (~(SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->csxPinMux));
1075 uint32_t muxCsx = (config->csxPinMux == kSEMC_MUXRDY) ?
1076 (SEMC_IOCR_DBI_CSX - 1U) :
1077 ((config->csxPinMux == kSEMC_MUXA8) ? SEMC_IOCR_DBI_CSX_A8 : SEMC_IOCR_DBI_CSX);
1078
1079
1080 base->IOCR = iocReg | (muxCsx << (uint32_t)config->csxPinMux);
1081
1082 result = SEMC_CovertMemorySize(config->memsize_kbytes, &memsize);
1083 if (result != kStatus_Success)
1084 {
1085 return result;
1086 }
1087 base->BR[7] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK;
1088
1089
1090 base->DBICR0 =
1091 SEMC_DBICR0_PS(config->portSize) | SEMC_DBICR0_BL(config->burstLen) | SEMC_DBICR0_COL(config->columnAddrBitNum);
1092
1093 timing = SEMC_DBICR1_CES(SEMC_ConvertTiming(config->tCsxSetup_Ns, clkSrc_Hz));
1094 timing |= SEMC_DBICR1_CEH(SEMC_ConvertTiming(config->tCsxHold_Ns, clkSrc_Hz));
1095 timing |= SEMC_DBICR1_WEL(SEMC_ConvertTiming(config->tWexLow_Ns, clkSrc_Hz));
1096 timing |= SEMC_DBICR1_WEH(SEMC_ConvertTiming(config->tWexHigh_Ns, clkSrc_Hz));
1097 timing |= SEMC_DBICR1_REL(SEMC_ConvertTiming(config->tRdxLow_Ns, clkSrc_Hz));
1098 timing |= SEMC_DBICR1_REH(SEMC_ConvertTiming(config->tRdxHigh_Ns, clkSrc_Hz));
1099 #if defined(SEMC_DBICR1_CEITV_MASK)
1100 timing |= SEMC_DBICR1_CEITV(SEMC_ConvertTiming(config->tCsxInterval_Ns, clkSrc_Hz));
1101 #endif
1102
1103
1104 base->DBICR1 = timing;
1105
1106 #if defined(SEMC_DBICR2_CEITV_MASK)
1107 timing = SEMC_DBICR2_CEITV(SEMC_ConvertTiming(config->tCsxInterval_Ns, clkSrc_Hz));
1108
1109
1110 base->DBICR2 = timing;
1111 #endif
1112
1113 return SEMC_ConfigureIPCommand(base, ((uint8_t)config->portSize + 1U));
1114 }
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130 status_t SEMC_SendIPCommand(
1131 SEMC_Type *base, semc_mem_type_t memType, uint32_t address, uint32_t command, uint32_t write, uint32_t *read)
1132 {
1133 uint32_t cmdMode;
1134 bool readCmd = false;
1135 bool writeCmd = false;
1136 status_t result;
1137
1138
1139 base->INTR |= SEMC_INTR_IPCMDDONE_MASK;
1140
1141 base->IPCR0 = address;
1142
1143
1144 cmdMode = (uint32_t)command & 0x0FU;
1145 switch (memType)
1146 {
1147 case kSEMC_MemType_NAND:
1148 readCmd = (cmdMode == (uint32_t)kSEMC_NANDCM_CommandAddressRead) ||
1149 (cmdMode == (uint32_t)kSEMC_NANDCM_CommandRead) || (cmdMode == (uint32_t)kSEMC_NANDCM_Read);
1150 writeCmd = (cmdMode == (uint32_t)kSEMC_NANDCM_CommandAddressWrite) ||
1151 (cmdMode == (uint32_t)kSEMC_NANDCM_CommandWrite) || (cmdMode == (uint32_t)kSEMC_NANDCM_Write);
1152 break;
1153 case kSEMC_MemType_NOR:
1154 case kSEMC_MemType_8080:
1155 readCmd = (cmdMode == (uint32_t)kSEMC_NORDBICM_Read);
1156 writeCmd = (cmdMode == (uint32_t)kSEMC_NORDBICM_Write);
1157 break;
1158 case kSEMC_MemType_SRAM:
1159 readCmd = (cmdMode == (uint32_t)kSEMC_SRAMCM_ArrayRead) || (cmdMode == (uint32_t)kSEMC_SRAMCM_RegRead);
1160 writeCmd = (cmdMode == (uint32_t)kSEMC_SRAMCM_ArrayWrite) || (cmdMode == (uint32_t)kSEMC_SRAMCM_RegWrite);
1161 break;
1162 case kSEMC_MemType_SDRAM:
1163 readCmd = (cmdMode == (uint32_t)kSEMC_SDRAMCM_Read);
1164 writeCmd = (cmdMode == (uint32_t)kSEMC_SDRAMCM_Write) || (cmdMode == (uint32_t)kSEMC_SDRAMCM_Modeset);
1165 break;
1166 default:
1167 assert(false);
1168 break;
1169 }
1170
1171 if (writeCmd)
1172 {
1173
1174 base->IPTXDAT = write;
1175 }
1176
1177
1178 base->IPCMD = command | SEMC_IPCMD_KEY(SEMC_IPCOMMANDMAGICKEY);
1179
1180 result = SEMC_IsIPCommandDone(base);
1181 if (result != kStatus_Success)
1182 {
1183 return result;
1184 }
1185
1186 if (readCmd)
1187 {
1188
1189 *read = base->IPRXDAT;
1190 }
1191
1192 return kStatus_Success;
1193 }
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203 status_t SEMC_IPCommandNandWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes)
1204 {
1205 assert(data != NULL);
1206
1207 status_t result = kStatus_Success;
1208 uint16_t ipCmd;
1209 uint32_t tempData = 0;
1210
1211
1212 ipCmd = SEMC_BuildNandIPCommand(0, kSEMC_NANDAM_ColumnRow, kSEMC_NANDCM_Write);
1213 while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX)
1214 {
1215
1216 (void)SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX);
1217 result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, *(uint32_t *)(void *)data, NULL);
1218 if (result != kStatus_Success)
1219 {
1220 break;
1221 }
1222
1223 data += SEMC_IPCOMMANDDATASIZEBYTEMAX;
1224 size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX;
1225 }
1226
1227 if ((result == kStatus_Success) && (size_bytes != 0x00U))
1228 {
1229 (void)SEMC_ConfigureIPCommand(base, (uint8_t)size_bytes);
1230
1231 while (size_bytes != 0x00U)
1232 {
1233 size_bytes--;
1234 tempData <<= SEMC_BYTE_NUMBIT;
1235 tempData |= data[size_bytes];
1236 }
1237
1238 result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, tempData, NULL);
1239 }
1240
1241 return result;
1242 }
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252 status_t SEMC_IPCommandNandRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes)
1253 {
1254 assert(data != NULL);
1255
1256 status_t result = kStatus_Success;
1257 uint16_t ipCmd;
1258 uint32_t tempData = 0;
1259
1260
1261 (void)SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX);
1262
1263 ipCmd = SEMC_BuildNandIPCommand(0, kSEMC_NANDAM_ColumnRow, kSEMC_NANDCM_Read);
1264
1265 while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX)
1266 {
1267 result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, 0, (uint32_t *)(void *)data);
1268 if (result != kStatus_Success)
1269 {
1270 break;
1271 }
1272
1273 data += SEMC_IPCOMMANDDATASIZEBYTEMAX;
1274 size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX;
1275 }
1276
1277 if ((result == kStatus_Success) && (size_bytes != 0x00U))
1278 {
1279 (void)SEMC_ConfigureIPCommand(base, (uint8_t)size_bytes);
1280 result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, 0, &tempData);
1281
1282 while (size_bytes != 0x00U)
1283 {
1284 size_bytes--;
1285 *(data + size_bytes) = (uint8_t)((tempData >> (SEMC_BYTE_NUMBIT * size_bytes)) & 0xFFU);
1286 }
1287 }
1288
1289 return result;
1290 }
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300 status_t SEMC_IPCommandNorRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes)
1301 {
1302 assert(data != NULL);
1303
1304 uint32_t tempData = 0;
1305 status_t result = kStatus_Success;
1306 uint8_t dataSize = (uint8_t)base->NORCR0 & SEMC_NORCR0_PS_MASK;
1307
1308
1309 (void)SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX);
1310
1311 while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX)
1312 {
1313 result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, (uint32_t)kSEMC_NORDBICM_Read, 0,
1314 (uint32_t *)(void *)data);
1315 if (result != kStatus_Success)
1316 {
1317 break;
1318 }
1319
1320 data += SEMC_IPCOMMANDDATASIZEBYTEMAX;
1321 size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX;
1322 }
1323
1324 if ((result == kStatus_Success) && (size_bytes != 0x00U))
1325 {
1326 (void)SEMC_ConfigureIPCommand(base, (uint8_t)size_bytes);
1327 result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, (uint16_t)kSEMC_NORDBICM_Read, 0, &tempData);
1328 while (size_bytes != 0x00U)
1329 {
1330 size_bytes--;
1331 *(data + size_bytes) = (uint8_t)((tempData >> (SEMC_BYTE_NUMBIT * size_bytes)) & 0xFFU);
1332 }
1333 }
1334
1335 (void)SEMC_ConfigureIPCommand(base, dataSize);
1336 return result;
1337 }
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347 status_t SEMC_IPCommandNorWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes)
1348 {
1349 assert(data != NULL);
1350
1351 uint32_t tempData = 0;
1352 status_t result = kStatus_Success;
1353 uint8_t dataSize = (uint8_t)base->NORCR0 & SEMC_NORCR0_PS_MASK;
1354
1355
1356 while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX)
1357 {
1358
1359 (void)SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX);
1360 result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, (uint16_t)kSEMC_NORDBICM_Write,
1361 *(uint32_t *)(void *)data, NULL);
1362 if (result != kStatus_Success)
1363 {
1364 break;
1365 }
1366 size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX;
1367 data += SEMC_IPCOMMANDDATASIZEBYTEMAX;
1368 }
1369
1370 if ((result == kStatus_Success) && (size_bytes != 0x00U))
1371 {
1372 (void)SEMC_ConfigureIPCommand(base, (uint8_t)size_bytes);
1373
1374 while (size_bytes != 0x00U)
1375 {
1376 tempData |= ((uint32_t) * (data + size_bytes - 1U) << ((size_bytes - 1U) * SEMC_BYTE_NUMBIT));
1377 size_bytes--;
1378 }
1379
1380 result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, (uint16_t)kSEMC_NORDBICM_Write, tempData, NULL);
1381 }
1382 (void)SEMC_ConfigureIPCommand(base, dataSize);
1383
1384 return result;
1385 }