If we flash a RD-RW612-BGA binary into FRDM-RW612 the board will be locked, and we will no longer be able to write data into the flash until we unlock it.
The reason why it locks is because the Winbond flash on the FRDM board has a lock bit that is enabled when flashing the RD application.
Fortunately, there is a way to unlock it with the FlexSPI interface. In this document we will briefly show how to do this.
We will modify the frdmrw612_flexspi_nor_dma_tranfer SDK example. We're going to modify app.h, flexspi_nor_flash_ops.c and flexspi_nor_dma_transfer.c.
In app.h we modify/add some macros with the following values:
#define SECTOR_SIZE 0x10000 /* 64K */
#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 0
#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG1 1
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 2
#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 3
#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG2 4
#define NOR_CMD_LUT_SEQ_IDX_ERASECHIP 5
#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG3 6
#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 7
#define NOR_CMD_LUT_SEQ_IDX_READID 8
#define NOR_CMD_LUT_SEQ_IDX_WRITE 9
#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1 10
#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG2 11
#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG3 12
#define NOR_CMD_LUT_SEQ_IDX_READ_FAST 13
#define NOR_CMD_LUT_SEQ_IDX_ENABLE_RESET 14
#define NOR_CMD_LUT_SEQ_IDX_RESET_DEVICE 15
#define CUSTOM_LUT_LENGTH 64
/* Enable quad and update dummy cycle */
#define FLASH_QUAD_ENABLE 0xC740
Moving to flexspi_nor_flash_ops.c we will add/modify the following parameters:
In flexspi_nor_wait_bus_busy(FLEXSPI_Type *base):
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1;
Right after the previous function we are going to add these new functions:
status_t flexspi_nor_write_status1(FLEXSPI_Type *base, uint8_t status1)
{
flexspi_transfer_t flashXfer;
status_t status;
uint32_t writeValue = status1;
/* Make sure external flash is not in busy status. */
status = flexspi_nor_wait_bus_busy(base);
if (status != kStatus_Success)
{
return status;
}
/* Write enable */
status = flexspi_nor_write_enable(base, 0);
if (status != kStatus_Success)
{
return status;
}
/* Write the status register 1 */
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG1;
flashXfer.data = &writeValue;
flashXfer.dataSize = 1;
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) && defined(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK) && \
defined(FLEXSPI_AHBCR_CLRAHBTXBUF_MASK)
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;
}
status_t flexspi_nor_write_status2(FLEXSPI_Type *base, uint8_t status2)
{
flexspi_transfer_t flashXfer;
status_t status;
uint32_t writeValue = status2;
/* Make sure external flash is not in busy status. */
status = flexspi_nor_wait_bus_busy(base);
if (status != kStatus_Success)
{
return status;
}
/* Write enable */
status = flexspi_nor_write_enable(base, 0);
if (status != kStatus_Success)
{
return status;
}
/* Write the status register 1 */
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG2;
flashXfer.data = &writeValue;
flashXfer.dataSize = 1;
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) && defined(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK) && \
defined(FLEXSPI_AHBCR_CLRAHBTXBUF_MASK)
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;
}
status_t flexspi_nor_write_status3(FLEXSPI_Type *base, uint8_t status3)
{
flexspi_transfer_t flashXfer;
status_t status;
uint32_t writeValue = status3;
/* Make sure external flash is not in busy status. */
status = flexspi_nor_wait_bus_busy(base);
if (status != kStatus_Success)
{
return status;
}
/* Write enable */
status = flexspi_nor_write_enable(base, 0);
if (status != kStatus_Success)
{
return status;
}
/* Write the status register 1 */
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG3;
flashXfer.data = &writeValue;
flashXfer.dataSize = 1;
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) && defined(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK) && \
defined(FLEXSPI_AHBCR_CLRAHBTXBUF_MASK)
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;
}
In status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base):
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG1;
Delete status_t flexspi_nor_flash_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src, uint32_t length) & status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src).
Modify status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId) to:
status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId, uint16_t *deviceId)
Right after status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId, uint16_t *deviceId):
status_t flexspi_nor_get_status1(FLEXSPI_Type *base, uint8_t *status1)
{
uint32_t temp;
flexspi_transfer_t flashXfer;
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1;
flashXfer.data = &temp;
flashXfer.dataSize = 1;
status_t status = FLEXSPI_TransferBlocking(base, &flashXfer);
*status1 = temp;
/* Do software reset or clear AHB buffer directly. */
#if defined(FSL_FEATURE_SOC_OTFAD_COUNT) && defined(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK) && \
defined(FLEXSPI_AHBCR_CLRAHBTXBUF_MASK)
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;
}
status_t flexspi_nor_get_status2(FLEXSPI_Type *base, uint8_t *status2)
{
uint32_t temp;
flexspi_transfer_t flashXfer;
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG2;
flashXfer.data = &temp;
flashXfer.dataSize = 1;
status_t status = FLEXSPI_TransferBlocking(base, &flashXfer);
*status2 = temp;
/* Do software reset or clear AHB buffer directly. */
#if defined(FSL_FEATURE_SOC_OTFAD_COUNT) && defined(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK) && \
defined(FLEXSPI_AHBCR_CLRAHBTXBUF_MASK)
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;
}
status_t flexspi_nor_get_status3(FLEXSPI_Type *base, uint8_t *status3)
{
uint32_t temp;
flexspi_transfer_t flashXfer;
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG3;
flashXfer.data = &temp;
flashXfer.dataSize = 1;
status_t status = FLEXSPI_TransferBlocking(base, &flashXfer);
*status3 = temp;
/* Do software reset or clear AHB buffer directly. */
#if defined(FSL_FEATURE_SOC_OTFAD_COUNT) && defined(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK) && \
defined(FLEXSPI_AHBCR_CLRAHBTXBUF_MASK)
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;
}
Add a last function:
status_t flexspi_nor_reset_device(FLEXSPI_Type *base)
{
status_t status;
flexspi_transfer_t flashXfer;
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ENABLE_RESET;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_wait_bus_busy(base);
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_RESET_DEVICE;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_wait_bus_busy(base);
return status;
}
Then in the last file flexspi_nor_dma_transfer.c:
We are modifying the prototype flexspi_nor_get_vendor_id to:
extern status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId, uint16_t *deviceId);
And we are going to add the following prototypes:
extern status_t flexspi_nor_get_status1(FLEXSPI_Type *base, uint8_t *status1);
extern status_t flexspi_nor_get_status2(FLEXSPI_Type *base, uint8_t *status2);
extern status_t flexspi_nor_get_status3(FLEXSPI_Type *base, uint8_t *status3);
extern status_t flexspi_nor_reset_device(FLEXSPI_Type *base);
extern status_t flexspi_nor_write_status1(FLEXSPI_Type *base, uint8_t status1);
extern status_t flexspi_nor_write_status2(FLEXSPI_Type *base, uint8_t status2);
extern status_t flexspi_nor_write_status3(FLEXSPI_Type *base, uint8_t status3);
extern status_t flexspi_nor_erase_chip(FLEXSPI_Type *base);
In flexspi_device_config_t deviceconfig modify the following:
.dataValidTime = 2,
Modify the const uint32_t customLUT[CUSTOM_LUT_LENGTH] as follows:
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
/* Normal read mode -SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x13, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x20),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Fast read mode - SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x0C, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x20),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x0A, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Fast read quad mode - SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEC, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x20),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x0A, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),
/* Write Enable */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Erase Sector */
[4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x21, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x20),
/* Read ID */
[4 * NOR_CMD_LUT_SEQ_IDX_READID] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Write status 1 */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
/* Write status 2 */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG2] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x31, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
/* Write status 3 */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG3] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x11, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
/* Dummy write, do nothing when AHB write command is triggered. */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0),
/* Read status 1 register */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Read status 2 register */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG2] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Read status 3 register */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG3] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x15, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Erase whole chip */
[4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Enable reset */
[4 * NOR_CMD_LUT_SEQ_IDX_ENABLE_RESET] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x66, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Reset device */
[4 * NOR_CMD_LUT_SEQ_IDX_RESET_DEVICE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x99, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
};
In int main(void) add the following variables:
uint16_t deviceID = 0;
uint8_t status1 = 0, status2 = 0, status3 = 0;
in main, configure the DMAMUX as follows (this should be before DMA_Init(EXAMPLE_DMA):
/* Configure DMAMUX. */
RESET_PeripheralReset(kINPUTMUX_RST_SHIFT_RSTn);
INPUTMUX_Init(INPUTMUX);
INPUTMUX_AttachSignal(INPUTMUX, EXAMPLE_TX_CHANNEL, kINPUTMUX_FlexspiTxToDma0);
INPUTMUX_AttachSignal(INPUTMUX, EXAMPLE_RX_CHANNEL, kINPUTMUX_FlexspiRxToDma0);
/* Enable trigger. */
INPUTMUX_EnableSignal(INPUTMUX, kINPUTMUX_Dmac0InputTriggerFlexspiRxEna, true);
INPUTMUX_EnableSignal(INPUTMUX, kINPUTMUX_Dmac0InputTriggerFlexspiTxEna, true);
/* Turnoff clock to inputmux to save power. Clock is only needed to make changes */
INPUTMUX_Deinit(INPUTMUX);
in main, delete all the code from PRINTF("\r\nFLEXSPI dma example started!\r\n"); to one line before the last while(1).
Before that while, add the following code:
PRINTF("\r\nFLEXSPI Unlock code started!\r\n");
/* FLEXSPI init */
flexspi_nor_flash_init(EXAMPLE_FLEXSPI);
/* Get vendor ID. */
status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID, &deviceID);
if (status != kStatus_Success)
{
PRINTF("Error getting flash ids: 0x%x\r\n", status);
return status;
}
PRINTF("Vendor ID: 0x%x\r\n", vendorID);
PRINTF("Device ID: 0x%x\r\n", deviceID);
/* Get Status 1 */
status = flexspi_nor_get_status1(EXAMPLE_FLEXSPI, &status1);
if (status != kStatus_Success)
{
PRINTF("Error getting status1: 0x%x\r\n", status);
return status;
}
PRINTF("Status 1: 0x%x\r\n", status1);
/* Get Status 2 */
status = flexspi_nor_get_status2(EXAMPLE_FLEXSPI, &status2);
if (status != kStatus_Success)
{
PRINTF("Error getting status2: 0x%x\r\n", status);
return status;
}
PRINTF("Status 2: 0x%x\r\n", status2);
/* Get Status 3 */
status = flexspi_nor_get_status3(EXAMPLE_FLEXSPI, &status3);
if (status != kStatus_Success)
{
PRINTF("Error getting status3: 0x%x\r\n", status);
return status;
}
PRINTF("Status 3: 0x%x\r\n", status3);
if(status2 & 0x01) {
PRINTF("Error, The Flash Status register is locked! Disconnect and connect the board with the ISP button pressed to clear it and try again.\r\n");
return 0;
}
status1 = 0x00;
status2 = 0x02;
/* Write 0s to Status 1 */
status = flexspi_nor_write_status1(EXAMPLE_FLEXSPI, status1);
if (status != kStatus_Success)
{
PRINTF("Error writing status1: 0x%x\r\n", status);
return status;
}
/* Write 0x02 (Quad enabled only) to Status 2 */
status = flexspi_nor_write_status2(EXAMPLE_FLEXSPI, status2);
if (status != kStatus_Success)
{
PRINTF("Error writing status2: 0x%x\r\n", status);
return status;
}
/* Get Status 1 */
status = flexspi_nor_get_status1(EXAMPLE_FLEXSPI, &status1);
if (status != kStatus_Success)
{
PRINTF("Error getting status1: 0x%x\r\n", status);
return status;
}
PRINTF("Status 1: 0x%x\r\n", status1);
/* Get Status 2 */
status = flexspi_nor_get_status2(EXAMPLE_FLEXSPI, &status2);
if (status != kStatus_Success)
{
PRINTF("Error getting status2: 0x%x\r\n", status);
return status;
}
PRINTF("Status 2: 0x%x\r\n", status2);
PRINTF("Erasing the whole chip, it will take several minutes to complete. \r\n");
status = flexspi_nor_erase_chip(EXAMPLE_FLEXSPI);
if (status != kStatus_Success)
{
PRINTF("Error erasing: 0x%x\r\n", status);
return status;
}
PRINTF("Chip erased!\r\n");
Now we need to compile. But first, we need to link the application to RAM.
Please right click on the project and go to Properties. in C/C++ Build go to Settings.
In MCU Linker, select Managed Linker Script and check the Link application to RAM box. Apply and close.
Now compile the example in MCUXpresso. Once compiled, get the binary. Go to the Debug folder in the project, and you will see an .axf file. Right click on the file and select Binary Utilities > Create binary. Now, we need to modify that binary. Open you preferred binary editor and delete everything from 0x0 to 0x17FFFFFFF. The first address in the binary (0x0) must have the data from 0x18000000.
Now we can flash the binary. We are going to do this with blhost. 2 USB C cables are needed. We are going to connect them via J10 and J8. But first we need to setup the board in ISP mode.
Connect J8 to the PC. Press the ISP button (SW3) and with the button pressed connect the board via J10.
In blhost run the following:
blhost -u 0x1fc9,0x0020 get-property 1
Disconnect and connect (J10) your board with the ISP button pressed.
Now run the following (YOUR BINARY should be the path and file in which the binary is located):
blhost -u 0x1fc9,0x0020 -- fill-memory 0x20001000 0x4 0xC0100002
blhost -u 0x1fc9,0x0020 -- configure-memory 0x9 0x20001000
blhost -u 0x1fc9,0x0020 -- get-property 0x19 0x9
blhost -u 0x1fc9,0x0020 -- write-memory 0x20000000 <YOUR BINARY>.bin
blhost -u 0x1fc9,0x0020 -- execute 0x2000026c 0x20000000 0x20120000
If the above steps were correct, you should be able to flash your board again. Please try with a hello world example in MCUXpresso.
View full article