149 lines
3.9 KiB
C
149 lines
3.9 KiB
C
/*
|
|
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
|
* Copyright 2016-2019 NXP
|
|
* All rights reserved.
|
|
*
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "sdk/drivers/flexspi/fsl_flexspi.h"
|
|
#include "internal_flash.h"
|
|
#include "boards/flash_config.h"
|
|
#include "supervisor/internal_flash.h"
|
|
#include "supervisor/linker.h"
|
|
|
|
STATIC uint8_t _busy_bit_shift;
|
|
STATIC bool _busy_bit_polarity;
|
|
STATIC bool _inited = false;
|
|
|
|
void flexspi_nor_init(void) {
|
|
// Copy busy bit info into RAM so we can use if when flash isn't available.
|
|
_busy_bit_shift = qspiflash_config.memConfig.busyOffset;
|
|
_busy_bit_polarity = qspiflash_config.memConfig.busyBitPolarity;
|
|
_inited = true;
|
|
}
|
|
|
|
STATIC status_t PLACE_IN_ITCM(flexspi_nor_write_enable)(FLEXSPI_Type * base, uint32_t baseAddr)
|
|
{
|
|
flexspi_transfer_t flashXfer;
|
|
status_t status;
|
|
|
|
/* Write enable */
|
|
flashXfer.deviceAddress = baseAddr;
|
|
flashXfer.port = kFLEXSPI_PortA1;
|
|
flashXfer.cmdType = kFLEXSPI_Command;
|
|
flashXfer.SeqNumber = 1;
|
|
flashXfer.seqIndex = ROM_INDEX_WRITEENABLE;
|
|
|
|
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
|
|
|
return status;
|
|
}
|
|
|
|
STATIC status_t PLACE_IN_ITCM(flexspi_nor_wait_bus_busy)(FLEXSPI_Type * base)
|
|
{
|
|
/* Wait status ready. */
|
|
bool isBusy;
|
|
uint32_t readValue;
|
|
status_t status;
|
|
flexspi_transfer_t flashXfer;
|
|
|
|
flashXfer.deviceAddress = 0;
|
|
flashXfer.port = kFLEXSPI_PortA1;
|
|
flashXfer.cmdType = kFLEXSPI_Read;
|
|
flashXfer.SeqNumber = 1;
|
|
flashXfer.seqIndex = ROM_INDEX_READSTATUSREG;
|
|
flashXfer.data = &readValue;
|
|
flashXfer.dataSize = 1;
|
|
|
|
do
|
|
{
|
|
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
|
|
|
if (status != kStatus_Success) {
|
|
return status;
|
|
}
|
|
bool busyBit = (readValue >> _busy_bit_shift) & 0x1;
|
|
isBusy = busyBit != _busy_bit_polarity;
|
|
} while (isBusy);
|
|
|
|
return status;
|
|
}
|
|
|
|
status_t PLACE_IN_ITCM(flexspi_nor_flash_erase_sector)(FLEXSPI_Type * base, uint32_t address)
|
|
{
|
|
status_t status;
|
|
flexspi_transfer_t flashXfer;
|
|
|
|
/* Write enable */
|
|
flashXfer.deviceAddress = address;
|
|
flashXfer.port = kFLEXSPI_PortA1;
|
|
flashXfer.cmdType = kFLEXSPI_Command;
|
|
flashXfer.SeqNumber = 1;
|
|
flashXfer.seqIndex = ROM_INDEX_WRITEENABLE;
|
|
|
|
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
|
|
|
if (status != kStatus_Success) {
|
|
return status;
|
|
}
|
|
|
|
flashXfer.deviceAddress = address;
|
|
flashXfer.port = kFLEXSPI_PortA1;
|
|
flashXfer.cmdType = kFLEXSPI_Command;
|
|
flashXfer.SeqNumber = 1;
|
|
flashXfer.seqIndex = ROM_INDEX_ERASESECTOR;
|
|
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
|
|
|
if (status != kStatus_Success) {
|
|
return status;
|
|
}
|
|
|
|
status = flexspi_nor_wait_bus_busy(base);
|
|
|
|
/* Do software reset. */
|
|
FLEXSPI_SoftwareReset(base);
|
|
|
|
return status;
|
|
}
|
|
|
|
status_t PLACE_IN_ITCM(flexspi_nor_flash_page_program)(FLEXSPI_Type * base, uint32_t dstAddr, const uint32_t *src)
|
|
{
|
|
status_t status;
|
|
flexspi_transfer_t flashXfer;
|
|
|
|
/* Write enable */
|
|
status = flexspi_nor_write_enable(base, dstAddr);
|
|
|
|
if (status != kStatus_Success) {
|
|
return status;
|
|
}
|
|
|
|
/* Prepare page program command */
|
|
flashXfer.deviceAddress = dstAddr;
|
|
flashXfer.port = kFLEXSPI_PortA1;
|
|
flashXfer.cmdType = kFLEXSPI_Write;
|
|
flashXfer.SeqNumber = 1;
|
|
flashXfer.seqIndex = ROM_INDEX_PAGEPROGRAM;
|
|
flashXfer.data = (uint32_t *)src;
|
|
flashXfer.dataSize = FLASH_PAGE_SIZE;
|
|
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
|
|
|
if (status != kStatus_Success) {
|
|
return status;
|
|
}
|
|
|
|
status = flexspi_nor_wait_bus_busy(base);
|
|
|
|
/* Do software reset. */
|
|
#if defined(FSL_FEATURE_SOC_OTFAD_COUNT) && FSL_FEATURE_SOC_OTFAD_COUNT == 1
|
|
base->AHBCR |= FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK;
|
|
base->AHBCR &= ~(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK);
|
|
#else
|
|
FLEXSPI_SoftwareReset(base);
|
|
#endif
|
|
|
|
return status;
|
|
}
|