/* * Copyright 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_romapi.h" #include "fsl_debug_console.h" #include "fsl_cache.h" #include "pin_mux.h" #include "clock_config.h" #include "board.h" #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ #define FlexSpiInstance 0U #define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE #define FLASH_SIZE 0x800000UL /* 8MBytes */ #define FLASH_PAGE_SIZE 256UL /* 256Bytes */ #define FLASH_SECTOR_SIZE 0x1000UL /* 4KBytes */ #define FLASH_BLOCK_SIZE 0x10000UL /* 64KBytes */ #define BUFFER_LEN FLASH_PAGE_SIZE /******************************************************************************* * Prototypes ******************************************************************************/ void error_trap(void); void app_finalize(void); /******************************************************************************* * Variables ******************************************************************************/ /*! @brief config serial NOR option */ static serial_nor_config_option_t option = { .option0.U = 0xc0000007U, .option1.U = 0U, }; /*! @brief FLEXSPI NOR flash driver Structure */ static flexspi_nor_config_t norConfig; /*! @brief Buffer for program */ static uint8_t s_buffer[BUFFER_LEN]; /*! @brief Buffer for readback */ static uint8_t s_buffer_rbc[BUFFER_LEN]; status_t FLEXSPI_NorFlash_GetVendorID(uint32_t instance, uint32_t *vendorID); /******************************************************************************* * Code ******************************************************************************/ /* * @brief Gets called when an error occurs. * * @details Print error message and trap forever. */ void error_trap(void) { PRINTF("\r\n\r\n\r\n\t---- HALTED DUE TO FLEXSPI NOR ERROR! ----"); while (1) { } } /* * @brief Gets called when the app is complete. * * @details Print finshed message and trap forever. */ void app_finalize(void) { /* Print finished message. */ PRINTF("\r\n End of FLEXSPI NOR Example! \r\n"); while (1) { } } status_t FLEXSPI_NorFlash_GetVendorID(uint32_t instance, uint32_t *vendorID) { uint32_t lut_seq[4]; memset(lut_seq, 0, sizeof(lut_seq)); // Read manufacturer ID lut_seq[0] = FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x9F, READ_SDR, FLEXSPI_1PAD, 4); ROM_FLEXSPI_NorFlash_UpdateLut(instance, NOR_CMD_LUT_SEQ_IDX_READID, (const uint32_t *)lut_seq, 1U); flexspi_xfer_t xfer; xfer.operation = kFLEXSPIOperation_Read; xfer.seqId = NOR_CMD_LUT_SEQ_IDX_READID; xfer.seqNum = 1U; xfer.baseAddress = 0U; xfer.isParallelModeEnable = false; xfer.rxBuffer = vendorID; xfer.rxSize = 1U; uint32_t status = ROM_FLEXSPI_NorFlash_CommandXfer(instance, &xfer); if (*vendorID != kSerialFlash_ISSI_ManufacturerID) { status = kStatus_ROM_FLEXSPINOR_Flash_NotFound; return status; } return status; } int main(void) { status_t status; uint32_t i = 0U; uint32_t vendorID = 0U; uint32_t serialNorAddress; /* Address of the serial nor device location */ uint32_t FlexSPISerialNorAddress; /* Address of the serial nor device in FLEXSPI memory */ uint32_t serialNorTotalSize; uint32_t serialNorSectorSize; uint32_t serialNorPageSize; BOARD_ConfigMPU(); BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); PRINTF("\r\n FLEXSPI NOR example started!\r\n"); /* Clean up FLEXSPI NOR flash driver Structure */ memset(&norConfig, 0U, sizeof(flexspi_nor_config_t)); /* Setup FLEXSPI NOR Configuration Block */ status = ROM_FLEXSPI_NorFlash_GetConfig(FlexSpiInstance, &norConfig, &option); if (status == kStatus_Success) { PRINTF("\r\n Successfully get FLEXSPI NOR configuration block\r\n "); } else { PRINTF("\r\n Get FLEXSPI NOR configuration block failure!\r\n"); error_trap(); } /* Initializes the FLEXSPI module for the other FLEXSPI APIs */ status = ROM_FLEXSPI_NorFlash_Init(FlexSpiInstance, &norConfig); if (status == kStatus_Success) { PRINTF("\r\n Successfully init FLEXSPI serial NOR flash\r\n "); } else { PRINTF("\r\n Erase sector failure !\r\n"); error_trap(); } /* Perform software reset after initializing flexspi module */ ROM_FLEXSPI_NorFlash_ClearCache(FlexSpiInstance); /* Probe device presence by verifying Manufacturer ID */ status = FLEXSPI_NorFlash_GetVendorID(FlexSpiInstance, &vendorID); if (status == kStatus_Success) { PRINTF("\r\n Serial NOR flash has been found successfully\r\n "); PRINTF("Vendor ID: 0x%x\r\n", vendorID); } else { PRINTF("\r\n Serial flash can not be found!\r\n"); error_trap(); } serialNorTotalSize = norConfig.memConfig.sflashA1Size; serialNorSectorSize = norConfig.sectorSize; serialNorPageSize = norConfig.pageSize; /* Print serial NOR flash information */ PRINTF("\r\n Serial NOR flash Information: "); PRINTF("\r\n Total program flash size:\t%d KB, Hex: (0x%x)", (serialNorTotalSize / 1024U), serialNorTotalSize); PRINTF("\r\n Program flash sector size:\t%d KB, Hex: (0x%x) ", (serialNorSectorSize / 1024U), serialNorSectorSize); PRINTF("\r\n Program flash page size:\t%d B, Hex: (0x%x)\r\n", serialNorPageSize, serialNorPageSize); /* * SECTOR_INDEX_FROM_END = 1 means the last sector, * SECTOR_INDEX_FROM_END = 2 means (the last sector - 1) ... */ #ifndef SECTOR_INDEX_FROM_END #define SECTOR_INDEX_FROM_END 1U #endif /* Erase a sector from target device dest address */ serialNorAddress = serialNorTotalSize - (SECTOR_INDEX_FROM_END * serialNorSectorSize); FlexSPISerialNorAddress = EXAMPLE_FLEXSPI_AMBA_BASE + serialNorAddress; /* Erase one sector. */ PRINTF("\r\n Erasing serial NOR flash over FLEXSPI"); status = ROM_FLEXSPI_NorFlash_Erase(FlexSpiInstance, &norConfig, serialNorAddress, serialNorSectorSize); if (status == kStatus_Success) { /* Print message for user. */ PRINTF("\r\n Successfully erased one sector of NOR flash device 0x%x -> 0x%x\r\n", serialNorAddress, (serialNorAddress + serialNorSectorSize)); } else { PRINTF("\r\n Erase sector failure!\r\n"); error_trap(); } PRINTF("\r\n Program a buffer to a page of NOR flash"); /* Prepare user buffer. */ for (i = 0; i < BUFFER_LEN; i++) { s_buffer[i] = i; } /* Program user buffer into FLEXSPI NOR flash */ status = ROM_FLEXSPI_NorFlash_ProgramPage(FlexSpiInstance, &norConfig, serialNorAddress, (const uint32_t *)s_buffer); if (status != kStatus_Success) { PRINTF("\r\n Page program failure!\r\n"); error_trap(); } DCACHE_InvalidateByRange(FlexSPISerialNorAddress, sizeof(s_buffer_rbc)); /* Verify programming by reading back from FLEXSPI memory directly */ memcpy(s_buffer_rbc, (void *)(FlexSPISerialNorAddress), sizeof(s_buffer_rbc)); if (memcmp(s_buffer_rbc, s_buffer, sizeof(s_buffer)) == 0) { PRINTF("\r\n Successfully programmed and verified location FLEXSPI memory 0x%x -> 0x%x \r\n", (FlexSPISerialNorAddress), (FlexSPISerialNorAddress + sizeof(s_buffer))); } else { PRINTF("\r\n Program data - read out data value incorrect!\r\n "); error_trap(); } /* Erase the context we have progeammed before*/ status = ROM_FLEXSPI_NorFlash_Erase(FlexSpiInstance, &norConfig, serialNorAddress, serialNorSectorSize); run_bootloader_ctx_t boot_para; boot_para.B.imageIndex = 0; boot_para.B.serialBootInterface = kEnterBootloader_SerialInterface_USB; boot_para.B.bootMode = kEnterBootloader_Mode_SerialDownloader; boot_para.B.tag = kEnterBootloader_Tag; //uint32_t arg = 0xeb100000; ROM_RunBootloader(&boot_para); app_finalize(); return 0; }