circuitpython/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

139 lines
3.7 KiB
C
Raw Normal View History

2019-11-02 11:52:26 -04:00
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_flexspi.h"
#include "internal_flash.h"
#include "boards/flash_config.h"
#include "supervisor/internal_flash.h"
#include "supervisor/linker.h"
2019-11-02 11:52:26 -04:00
STATIC status_t PLACE_IN_ITCM(flexspi_nor_write_enable)(FLEXSPI_Type * base, uint32_t baseAddr)
2019-11-02 11:52:26 -04:00
{
flexspi_transfer_t flashXfer;
status_t status;
/* Write enable */
flashXfer.deviceAddress = baseAddr;
2021-03-15 09:57:36 -04:00
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = ROM_INDEX_WRITEENABLE;
2019-11-02 11:52:26 -04:00
status = FLEXSPI_TransferBlocking(base, &flashXfer);
return status;
}
STATIC status_t PLACE_IN_ITCM(flexspi_nor_wait_bus_busy)(FLEXSPI_Type * base)
2019-11-02 11:52:26 -04:00
{
/* Wait status ready. */
bool isBusy;
uint32_t readValue;
status_t status;
flexspi_transfer_t flashXfer;
flashXfer.deviceAddress = 0;
2021-03-15 09:57:36 -04:00
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = ROM_INDEX_READSTATUSREG;
flashXfer.data = &readValue;
flashXfer.dataSize = 1;
2019-11-02 11:52:26 -04:00
do
{
status = FLEXSPI_TransferBlocking(base, &flashXfer);
2021-03-15 09:57:36 -04:00
if (status != kStatus_Success) {
2019-11-02 11:52:26 -04:00
return status;
}
size_t busyBit = readValue & (1U << qspiflash_config.memConfig.busyOffset);
isBusy = (qspiflash_config.memConfig.busyBitPolarity == 0 && busyBit != 0) ||
2021-03-15 09:57:36 -04:00
(qspiflash_config.memConfig.busyBitPolarity == 1 && busyBit == 0);
2019-11-02 11:52:26 -04:00
} while (isBusy);
return status;
}
2021-03-15 09:57:36 -04:00
status_t PLACE_IN_ITCM(flexspi_nor_flash_erase_sector)(FLEXSPI_Type * base, uint32_t address)
2019-11-02 11:52:26 -04:00
{
status_t status;
flexspi_transfer_t flashXfer;
/* Write enable */
flashXfer.deviceAddress = address;
2021-03-15 09:57:36 -04:00
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = ROM_INDEX_WRITEENABLE;
2019-11-02 11:52:26 -04:00
status = FLEXSPI_TransferBlocking(base, &flashXfer);
2021-03-15 09:57:36 -04:00
if (status != kStatus_Success) {
2019-11-02 11:52:26 -04:00
return status;
}
flashXfer.deviceAddress = address;
2021-03-15 09:57:36 -04:00
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = ROM_INDEX_ERASESECTOR;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
2019-11-02 11:52:26 -04:00
2021-03-15 09:57:36 -04:00
if (status != kStatus_Success) {
2019-11-02 11:52:26 -04:00
return status;
}
status = flexspi_nor_wait_bus_busy(base);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
return status;
}
2021-03-15 09:57:36 -04:00
status_t PLACE_IN_ITCM(flexspi_nor_flash_page_program)(FLEXSPI_Type * base, uint32_t dstAddr, const uint32_t *src)
2019-11-02 11:52:26 -04:00
{
status_t status;
flexspi_transfer_t flashXfer;
/* Write enable */
status = flexspi_nor_write_enable(base, dstAddr);
2021-03-15 09:57:36 -04:00
if (status != kStatus_Success) {
2019-11-02 11:52:26 -04:00
return status;
}
/* Prepare page program command */
flashXfer.deviceAddress = dstAddr;
2021-03-15 09:57:36 -04:00
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) {
2019-11-02 11:52:26 -04:00
return status;
}
status = flexspi_nor_wait_bus_busy(base);
/* Do software reset. */
2021-03-15 09:57:36 -04:00
#if defined(FSL_FEATURE_SOC_OTFAD_COUNT)
2019-11-02 11:52:26 -04:00
base->AHBCR |= FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK;
base->AHBCR &= ~(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK);
2021-03-15 09:57:36 -04:00
#else
2019-11-02 11:52:26 -04:00
FLEXSPI_SoftwareReset(base);
2021-03-15 09:57:36 -04:00
#endif
2019-11-02 11:52:26 -04:00
return status;
}