Can not erase external flash W25Q64JVSSIQ

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Can not erase external flash W25Q64JVSSIQ

1,347 Views
xuanthodo
Contributor I

Hi everyone, 

I'm using Teensy4.1 Board. It include MIMXRT1062DVJ6B and external flash W25Q64JVSSIQ.

I used evkmimxrt1060_flexspi_nor_polling_transfer to read, write and erase the external flash.

But i have issues: Cannot erase sector 3,4,6,7. In while others can be erased.

Below is my configuration and test:

- boot.conf

 

#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__)
__attribute__((section(".boot_hdr.conf"), used))
#elif defined(__ICCARM__)
#pragma location = ".boot_hdr.conf"
#endif

const flexspi_nor_config_t qspiflash_config = {
    .memConfig =
        {
            .tag                  = FLEXSPI_CFG_BLK_TAG,
            .version              = FLEXSPI_CFG_BLK_VERSION,
            .readSampleClksrc=kFlexSPIReadSampleClk_LoopbackFromDqsPad,
            .csHoldTime           = 3u,
            .csSetupTime          = 3u,
            .controllerMiscOption = (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable),
            .deviceType           = kFlexSpiDeviceType_SerialNOR,
            .sflashPadType        = kSerialFlash_4Pads,
            .serialClkFreq        = kFlexSpiSerialClk_133MHz,
            .sflashA1Size         = 8u * 1024u * 1024u,
            .lookupTable =
                {
                    // Read LUTs
                    [0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
                    [1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),

                    // Read Status LUTs
                    [4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04),

                    // Write Enable LUTs
                    [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x0),

                    // Erase Sector LUTs
                    [4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 0x18),

                    // Erase Block LUTs
                    [4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8, RADDR_SDR, FLEXSPI_1PAD, 0x18),

                    // Pape Program LUTs
                    [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18),
                    [4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0),

                    // Erase Chip LUTs
                    [4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0x0),
                },
        },
    .pageSize           = 256u,
    .sectorSize         = 4u * 1024u,
    .ipcmdSerialClkFreq = 1u,
    .blockSize          = 64u * 1024u,
    .isUniformBlockSize = false,
};

 

- Test function:

 

 

/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2018 NXP
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_debug_console.h"
#include "board.h"
#include "hal/flash.h"
#include "fsl_cache.h"

#define BEGIN_SECTOR    8
#define END_SECTOR        20
#define BUFFER_SIZE         256

static void print_array(uint8_t *data , size_t size){
    DbgConsole_Printf("Array: [");
    for (size_t i = 0; i < size - 1; i++)
    {
        if((i+ 1) % 16  == 0){
            DbgConsole_Printf("%x,\r\n" , data[i]);
        }
        else{
            DbgConsole_Printf("%x," , data[i]);
        }
        
    }
    DbgConsole_Printf("%x]\r\n" , data[size-1]);
}
/*******************************************************************************
 * Definitions
 ******************************************************************************/
/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/
/* Program data buffer should be 4-bytes alignment, which can avoid busfault due to this memory region is configured as
   Device Memory by MPU. */
SDK_ALIGN(static uint8_t s_nor_program_buffer[BUFFER_SIZE] , 4);
static uint8_t s_nor_read_buffer[BUFFER_SIZE];

int flash_test(void)
{
    uint32_t i = 0;

    FLASH_init();
    for (i = 0; i < 0xFFU; i++)
    {
        s_nor_program_buffer[i] = i;
    }

    for (size_t sector_index = BEGIN_SECTOR;  sector_index < END_SECTOR; sector_index++)
    {
        DbgConsole_Printf("Erase sector %d\r\n" , sector_index);
        DbgConsole_Printf("Data Before Program:\r\n");
        FLASH_read(sector_index * SECTOR_SIZE, s_nor_read_buffer, 256);
        print_array(s_nor_read_buffer, 256);
        FLASH_erase_sector(sector_index * SECTOR_SIZE);
        DCACHE_InvalidateByRange(FLASH_SPI_AMBA_BASE + sector_index * SECTOR_SIZE , 256);
        DbgConsole_Printf("Data After Program:\r\n");
        FLASH_read(sector_index * SECTOR_SIZE, s_nor_read_buffer, 256);
        print_array(s_nor_read_buffer, 256);
    }
    


    while (1)
    {
    }
}

Erase flash:

 

extern void FLASH_erase_sector(const uint32_t address)
{
    flexspi_transfer_t flashXfer;

    flexspi_cache_status_t cacheStatus;
    // Disable Cache
    FLASH_disable_cache(&cacheStatus);

    /* Write enable */
    FLASH_write_enable(FLASH_SPI, address);
    
    flashXfer.deviceAddress = address;
    flashXfer.port          = FLASH_PORT;
    flashXfer.cmdType       = kFLEXSPI_Command;
    flashXfer.SeqNumber     = 1;
    flashXfer.seqIndex      = NOR_CMD_LUT_SEQ_IDX_ERASESECTOR;
    FLEXSPI_TransferBlocking(FLASH_SPI, &flashXfer);

    FLASH_wait_bus_busy(FLASH_SPI);
    /* Do software reset. */
    FLEXSPI_SoftwareReset(FLASH_SPI);
    // Enable Cache
    FLASH_enable_cache(cacheStatus);
}

 

Custom LUT:

static 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, 0x03, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
    [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, 0x0B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
    [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ(
        kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, 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, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18),
    [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ(
        kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),

    /* Read extend parameters */
    [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 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, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),

    /* Page Program - single mode */
    [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
    [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

    /* Page Program - quad mode */
    [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
    [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

    /* 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),

    /* Enable Quad mode */
    [4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x31, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),

    /* Read status register */
    [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

    /* Read status register 2*/
    [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 register 3*/
    [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG3] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x15, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

    /* Global Unlock*/
    [4 * NOR_CMD_LUT_SEQ_IDX_GLOBAL_UNLOCK] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x98, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x04),

    /* Erase Sector  */
    [4 * NOR_CMD_LUT_SEQ_IDX_INDIVIDUAL_UNLOCK] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x39, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
    /* 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),
};

Read flash:

 

extern bool FLASH_read(volatile const uint8_t *const start_addr_p, uint8_t data_p[const], const uint32_t size_bytes)
{    
    status_t status;
    flexspi_transfer_t flashXfer;

    flexspi_cache_status_t cacheStatus;

    // Disable Cache
    FLASH_disable_cache(&cacheStatus);

    /* Prepare read data command */
    flashXfer.deviceAddress = start_addr_p;
    flashXfer.port          = FLASH_PORT;
    flashXfer.cmdType       = kFLEXSPI_Read;
    flashXfer.SeqNumber     = 1;
    flashXfer.seqIndex      = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD;
    flashXfer.data          = (uint32_t *)data_p;
    flashXfer.dataSize      = size_bytes;

    // Flash Send Write Command
    status = FLEXSPI_TransferBlocking(FLASH_SPI, &flashXfer);

    //Wait Bus Busy
    FLASH_wait_bus_busy(FLASH_SPI);

    /* Do software reset*/
    FLEXSPI_SoftwareReset(FLASH_SPI);

    // Enable Cache
    FLASH_enable_cache(cacheStatus);
    
    return status;
}

 

 

Result

***************************************** Case Erase 3-4 (Failed)*********************************

erase3.png

erase4.png

 ***************************************** Case Erase 8-9-10 (Success)*********************************

 

xuanthodo_3-1670494138368.pngxuanthodo_4-1670494152785.png

xuanthodo_5-1670494163866.png

Please help me! 

Thank you so much.

 

Labels (1)
0 Kudos
Reply
4 Replies

1,338 Views
jay_heng
NXP Employee
NXP Employee

It is interesting, but from you 'erase3/4' picture, i don't see the data difference between Data Before Program and Data After Program.

If some block/sectors cannot be erased, you need to check Status Register-1

WB.PNG

0 Kudos
Reply

1,334 Views
xuanthodo
Contributor I

Thanks for your response,

From erase3/4 picture, It cause blocking process after I send erasing command sector 3,4. 
About Status Register-1, I checked that it's in PROTECTED BLOCK 0 and 1 (attached image).
So I still don't know why i can erase other sector (5,8,9,...) , in while it's in BLOCK 0 and 1.

image.png

0 Kudos
Reply

1,287 Views
CarlosGarabito
NXP TechSupport
NXP TechSupport

Hi @xuanthodo did you have the same issue with the internal memory?

0 Kudos
Reply

1,279 Views
xuanthodo
Contributor I

Can you give me an example for booting from internal memory and flash-api to read/write/erase it?
Thank you.

0 Kudos
Reply