1050 EVK HyperFlash content mismatch for second write

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

1050 EVK HyperFlash content mismatch for second write

781 Views
muratcakmak
Contributor II

Hi Everyone, 

I am working on 1050 EVK and using Hyperflash which is the default. 

If I run HyperFlash example from the SDK (boards\evkbimxrt1050\driver_examples\flexspi\hyper_flash\polling_transfer),

it works well which is great. 

The test sequence is like below; 

- Erase Flash

- Erase Sector

- Program the Page using the numbers from 1 to 255. 

- Compare the written content with the source.

So, if I put the above sequence into a loop, there is no problem, it works well. 

But if I will the input buffer with some magical numbers, for the first time, it works but after the second iteration, the content does not match. 

For example, filling the buffer with 0x12345678 (buffer_cast_to_32bit[0] = 0x12345678, buffer_cast_to_32bit[1] = 0x12345678 ...)

If I call "flexspi_nor_hyperflash_cfi(EXAMPLE_FLEXSPI);" function in the loop before erasing the flash, it does not make any difference but if I call the flexspi_hyper_flash_init() in the loop which called for each iteration, I can see the expected values in the flash. 

I assume there should be no need to call the flexspi_hyper_flash_init() before each writing operation, or is there any limitation in HyperFlash? I assume If I erase a sector, the second (or others) should not be a problem. 

Am I missing something? Or any idea?

Thank you.

Murat

Labels (1)
Tags (1)
0 Kudos
2 Replies

697 Views
Sabina_Bruce
NXP Employee
NXP Employee

Hello Murat,

Hope you are doing well.

Could you please confirm the board version you are working with(EVK or EVKB) as well as the SDK and IDE version.

Also, I am trying to reproduce this behavior from my end, but could you tell me which buffer you are writing to. 

Best Regards,

Sabina

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

----------------------------------------------------------------------------------------------------------------------- 

0 Kudos

697 Views
mjbcswitzerland
Specialist V

Hi Murat

See the following

https://www.utasker.com/iMX/RT1050.html

I now have a Hyper Flash driver in the uTasker project that allows it to be used for parameter storage and file system storage in addition to code storage.

The SDK examples only show reading and programming a page of data (512 bytes) and don't solve the complexity of writing and reading random data at any address and any length - since the Hyperflash is short word oriented internally this needs to be respected and interface routines must handle things accordingly.

I don't know whether this is your problem but if you load the binary at the link you can play around with reading, writing and deleting data on its command line menu (I/O menu using the commands "sd" to display storage locations and word sizes, "sm" storage modify to modify locations in Hyper Flash, "sf" storage fill for filling areas with data, and "se" storage erase to erase. You can also view the complete 64 MByte Hyper Flash content on the USB interface as a binary file.

These are the read and write interfaces in the uTasker Flash driver showing the concept of use the flash as random byte read/write memory.

    switch (ucCommand) {
    case READ_DATA_BYTES:
        {
            unsigned char ulReadBuffer[2];
            MAX_FILE_LENGTH LengthToRead;
            if (DataLength == 0) {
                return;
            }
            if ((ulPageNumberOffset & 0x1) != 0) {                       // if reading from an odd address
                fnFlexSPI_Command(HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA, 2, ulReadBuffer, 0, (ulPageNumberOffset - 1)); // read two bytes from the even address
                *ucData++ = ulReadBuffer[1];                             // put the second byte into the user buffer
                if (--DataLength == 0) {
                    return;                                              // single odd address read complete
                }
                ulPageNumberOffset++;
            }
            // Reads from here are even address aligned
            //
            LengthToRead = (DataLength & ~1);                            // even length to read
            DataLength &= 1;                                             // remaining byte
            if (LengthToRead != 0) {                                     // if more that a single byte remaining
                fnFlexSPI_Command(HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA, LengthToRead, (unsigned char *)ucData, 0, ulPageNumberOffset); // read an even length of bytes
                ulPageNumberOffset += LengthToRead;
                ucData += LengthToRead;
            }
            if (DataLength != 0) {                                       // if one additional byte is to be read
                fnFlexSPI_Command(HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA, 1, (unsigned char *)ucData, 0, ulPageNumberOffset); // read an even length of bytes
            }
            return;
        }
    case PAGE_PROG:
        {
            unsigned long ulIntermediateBuffer = 0;
            unsigned char ucIntemediateWriteBuffer[SPI_FLASH_PAGE_LENGTH];
            int iStartIndex = (ulPageNumberOffset % SPI_FLASH_PAGE_LENGTH);
            unsigned long ulWriteDataLength = DataLength;
            fnFlexSPI_Command((HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE | WRITEENABLE_SEQUENCE_LENGTH), 0, 0, 0, ulPageNumberOffset);
            if ((ulPageNumberOffset & 0x1) != 0) {                       // first byte write is to an uneven address
                ucIntemediateWriteBuffer[iStartIndex - 1] = 0xff;        // prime 0xff so that it doesn't change data when programmed
                ulPageNumberOffset--;                                    // program to one address lower
                ulWriteDataLength++;                                     // program one extra byte
                ulIntermediateBuffer = 1;                                // the intermediate buffer needs to be used
            }
            if (((ulPageNumberOffset + ulWriteDataLength) & 0x1) != 0) { // final byte write is to an uneven address
                ucIntemediateWriteBuffer[iStartIndex + DataLength] = 0xff; // prime 0xff so that it doesn't change data when programmed
                ulWriteDataLength++;                                     // program one extra byte
                ulIntermediateBuffer |= 2;                               // the intermediate buffer needs to be used
            }
            if (ulIntermediateBuffer != 0) {
                uMemcpy(&ucIntemediateWriteBuffer[iStartIndex], (const void *)ucData, DataLength); // copy the user data to the intermediate buffer
                ucData = &ucIntemediateWriteBuffer[iStartIndex];
                if ((ulIntermediateBuffer & 0x1) != 0) {
                    ucData--;
                }
            }
            fnFlexSPI_Command((HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM | WRITEDATA_SEQUENCE_LENGTH), ulWriteDataLength, 0, (unsigned char *)ucData, ulPageNumberOffset);
        }
        break;
    case BLOCK_ERASE:                                                    // block erase - 256k
        fnFlexSPI_Command((HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE | WRITEENABLE_SEQUENCE_LENGTH), 0, 0, 0, ulPageNumberOffset);
        fnFlexSPI_Command((HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR | ERASESECTOR_SEQUENCE_LENGTH), 0, 0, 0, ulPageNumberOffset); // delete block
        break;
    case READ_JEDEC_ID:
        {
            unsigned char ucCommand[2] = {0x00, CFI_ENTER};
            fnFlexSPI_Command(HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA, sizeof(ucCommand), 0, ucCommand, CFI_COMMAND_ADDRESS); // enter CFI (common flash interface)
            fnFlexSPI_Command(HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA, DataLength, (unsigned char *)ucData, 0, 0); // read the ID
            ucCommand[1] = RESET_ASO_EXIT;
            fnFlexSPI_Command(HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA, sizeof(ucCommand), 0, ucCommand, 0); // exit CFI
        }
        return;
    case READ_STATUS_REGISTER_1:
        {
            static const unsigned char ucCommand[2] = { 0x00, STATUS_REGISTER_READ };
            fnFlexSPI_Command(HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA, sizeof(ucCommand), 0, (unsigned char *)ucCommand, STATUS_REG__COMMAND_ADDRESS); // enter CFI (common flash interface)
            fnFlexSPI_Command(HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA, DataLength, (unsigned char *)ucData, 0, 0); // read the status register
        }
        return;
    default:
        _EXCEPTION("Unsupported command!");
        break;
    }

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos