SECTION("itcm") int rt_hw_flexspi_init(void) { flexspi_config_t config; status_t status; rt_uint32_t level; level = rt_hw_interrupt_disable(); // Set flexspi root clock to 166MHZ. const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U}; CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll); CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 26); /* Set PLL3 PFD0 clock 332MHZ. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 83M, DDR mode, internal clock 42M. */ /*Get FLEXSPI default settings and configure the flexspi. */ FLEXSPI_GetDefaultConfig(&config); /*Set AHB buffer size for reading data through AHB bus. */ config.ahbConfig.enableAHBPrefetch = true; /*Allow AHB read start address do not follow the alignment requirement. */ config.ahbConfig.enableReadAddressOpt = true; /* enable diff clock and DQS */ config.enableSckBDiffOpt = true; config.rxSampleClock = kFLEXSPI_ReadSampleClkExternalInputFromDqsPad; config.enableCombination = true; FLEXSPI_Init(FLEXSPI, &config); /* Configure flash settings according to serial flash feature. */ FLEXSPI_SetFlashConfig(FLEXSPI, &deviceconfig, kFLEXSPI_PortA1); /* Update LUT table. */ FLEXSPI_UpdateLUT(FLEXSPI, 0, customLUT, CUSTOM_LUT_LENGTH); /* Do software reset. */ FLEXSPI_SoftwareReset(FLEXSPI); status = flexspi_nor_hyperflash_cfi(FLEXSPI); /* Get vendor ID. */ if (status != kStatus_Success) { FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return status; } FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return 0; }
SECTION("itcm") status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) { status_t status; flexspi_transfer_t flashXfer; rt_uint32_t level; level = rt_hw_interrupt_disable(); FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); /* Write enable */ status = flexspi_nor_write_enable(base, address); if (status != kStatus_Success) { FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return status; } flashXfer.deviceAddress = address; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Command; flashXfer.SeqNumber = 4; flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return status; } status = flexspi_nor_wait_bus_busy(base); rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLEXSPI_NOR_SECTOR_SIZE); rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLEXSPI_NOR_SECTOR_SIZE); FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return status; }
static void SetFlexSPIDiv(uint32_t div) { FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, div); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); // not sure why this is needed, but SDK example does it. }
void FLEXSPI_Init(FLEXSPI_Type *base, const flexspi_config_t *config) { uint32_t configValue = 0; uint8_t i = 0; #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the flexspi clock */ CLOCK_EnableClock(s_flexspiClock[FLEXSPI_GetInstance(base)]); #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Reset peripheral before configuring it. */ base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; FLEXSPI_SoftwareReset(base); /* Configure MCR0 configuration items. */ configValue = FLEXSPI_MCR0_RXCLKSRC(config->rxSampleClock) | FLEXSPI_MCR0_DOZEEN(config->enableDoze) | FLEXSPI_MCR0_IPGRANTWAIT(config->ipGrantTimeoutCycle) | FLEXSPI_MCR0_AHBGRANTWAIT(config->ahbConfig.ahbGrantTimeoutCycle) | FLEXSPI_MCR0_SCKFREERUNEN(config->enableSckFreeRunning) | FLEXSPI_MCR0_HSEN(config->enableHalfSpeedAccess) | FLEXSPI_MCR0_COMBINATIONEN(config->enableCombination) | FLEXSPI_MCR0_ATDFEN(config->ahbConfig.enableAHBWriteIpTxFifo) | FLEXSPI_MCR0_ATDFEN(config->ahbConfig.enableAHBWriteIpRxFifo) | FLEXSPI_MCR0_MDIS_MASK; base->MCR0 = configValue; /* Configure MCR1 configurations. */ configValue = FLEXSPI_MCR1_SEQWAIT(config->seqTimeoutCycle) | FLEXSPI_MCR1_AHBBUSWAIT(config->ahbConfig.ahbBusTimeoutCycle); base->MCR1 = configValue; /* Configure MCR2 configurations. */ configValue = FLEXSPI_MCR2_RESUMEWAIT(config->ahbConfig.resumeWaitCycle) | FLEXSPI_MCR2_SCKBDIFFOPT(config->enableSckBDiffOpt) | FLEXSPI_MCR2_SAMEDEVICEEN(config->enableSameConfigForAll) | FLEXSPI_MCR2_CLRAHBBUFOPT(config->ahbConfig.enableClearAHBBufferOpt); base->MCR2 = configValue; /* Configure AHB control items. */ base->AHBCR = FLEXSPI_AHBCR_PREFETCHEN(config->ahbConfig.enableAHBPrefetch) | FLEXSPI_AHBCR_BUFFERABLEEN(config->ahbConfig.enableAHBBufferable) | FLEXSPI_AHBCR_CACHABLEEN(config->ahbConfig.enableAHBCachable); /* Configure AHB rx buffers. */ for (i = 0; i < FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT - 1; i++) { base->AHBRXBUFCR0[i] = FLEXSPI_AHBRXBUFCR0_PRIORITY(config->ahbConfig.buffer[i].priority) | FLEXSPI_AHBRXBUFCR0_MSTRID(config->ahbConfig.buffer[i].masterIndex) | FLEXSPI_AHBRXBUFCR0_BUFSZ(config->ahbConfig.buffer[i].bufferSize / 8); } /* Configure IP Fifo watermarks. */ base->IPRXFCR |= FLEXSPI_IPRXFCR_RXWMRK(config->rxWatermark / 8 - 1); base->IPTXFCR |= FLEXSPI_IPRXFCR_RXWMRK(config->txWatermark / 8 - 1); }
SECTION("itcm") status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src) { status_t status; flexspi_transfer_t flashXfer; rt_uint32_t level; level = rt_hw_interrupt_disable(); FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); /* Write neable */ status = flexspi_nor_write_enable(base, address); if (status != kStatus_Success) { rt_hw_interrupt_enable(level); return status; } /* Prepare page program command */ flashXfer.deviceAddress = address; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 2; flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM; flashXfer.data = (uint32_t *)src; flashXfer.dataSize = FLASH_PAGE_SIZE; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { rt_hw_interrupt_enable(level); return status; } status = flexspi_nor_wait_bus_busy(base); rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLASH_PAGE_SIZE); rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLASH_PAGE_SIZE); FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return status; }
int flexspi_nor_init(void) { uint32_t i = 0; flexspi_config_t config; status_t status; #ifdef XIP_EXTERNAL_FLASH return 0; #endif // Set flexspi root clock to 166MHZ. // NOTE! we assuem PLL3 (USBPLL1) has been locked to 480MHz already CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 26); /* Set PLL3 PFD0 clock 332MHZ. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 83M, DDR mode, internal clock 42M. */ SCB_DisableDCache(); PRINTF("FLEXSPI hyperflash example started!\r\n"); /*Get FLEXSPI default settings and configure the flexspi. */ FLEXSPI_GetDefaultConfig(&config); /*Set AHB buffer size for reading data through AHB bus. */ config.ahbConfig.enableAHBPrefetch = true; /* enable diff clock and DQS */ config.enableSckBDiffOpt = true; config.rxSampleClock = kFLEXSPI_ReadSampleClkExternalInputFromDqsPad; config.enableCombination = true; FLEXSPI_Init(FLEXSPI, &config); /* Configure flash settings according to serial flash feature. */ FLEXSPI_SetFlashConfig(FLEXSPI, &deviceconfig, kFLEXSPI_PortA1); /* Update LUT table. */ FLEXSPI_UpdateLUT(FLEXSPI, 0, customLUT, CUSTOM_LUT_LENGTH); /* Do software reset. */ FLEXSPI_SoftwareReset(FLEXSPI); status = flexspi_nor_hyperflash_cfi(FLEXSPI); /* Get vendor ID. */ if (status != kStatus_Success) { return status; } return 0; /* Erase sectors. */ PRINTF("Erasing Serial NOR over FlexSPI...\r\n"); status = flexspi_nor_flash_erase_sector(FLEXSPI, SECTOR * SECTOR_SIZE); if (status != kStatus_Success) { PRINTF("Erase sector failure !\r\n"); return -1; } /* Do software reset. */ FLEXSPI_SoftwareReset(FLEXSPI); memset(s_hyperflash_program_buffer, 0xFF, sizeof(s_hyperflash_program_buffer)); memcpy(s_hyperflash_read_buffer, (void *)(FlexSPI_AMBA_BASE + SECTOR * SECTOR_SIZE), sizeof(s_hyperflash_read_buffer)); if (memcmp(s_hyperflash_program_buffer, s_hyperflash_read_buffer, sizeof(s_hyperflash_program_buffer))) { PRINTF("Erase data - read out data value incorrect !\r\n "); return -1; } else { PRINTF("Erase data - successfully. \r\n"); } for (i = 0; i < sizeof(s_hyperflash_program_buffer); i++) { s_hyperflash_program_buffer[i] = i & 0xFFU; } status = flexspi_nor_flash_page_program(FLEXSPI, SECTOR * SECTOR_SIZE, (void *)s_hyperflash_program_buffer); if (status != kStatus_Success) { PRINTF("Page program failure !\r\n"); return -1; } /* Program finished, speed the clock to 166M. */ FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); /* Do software reset to reset AHB buffer. */ FLEXSPI_SoftwareReset(FLEXSPI); memcpy(s_hyperflash_read_buffer, (void *)(FlexSPI_AMBA_BASE + SECTOR * SECTOR_SIZE), sizeof(s_hyperflash_read_buffer)); if (memcmp(s_hyperflash_read_buffer, s_hyperflash_program_buffer, sizeof(s_hyperflash_program_buffer)) != 0) { PRINTF("Program data - read out data value incorrect !\r\n "); return -1; } else { PRINTF("Program data - successfully. \r\n"); } while (1) { } }
void FLEXSPI_Deinit(FLEXSPI_Type *base) { /* Reset peripheral. */ FLEXSPI_SoftwareReset(base); }