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.

149 lines
3.9 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 "sdk/drivers/flexspi/fsl_flexspi.h"
2019-11-02 11:52:26 -04:00
#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 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)
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;
}
bool busyBit = (readValue >> _busy_bit_shift) & 0x1;
isBusy = busyBit != _busy_bit_polarity;
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;
}