This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] PROCESSOR-SDK-AM64X: Macronix OSPI NOR Flash Integration Guide

Part Number: PROCESSOR-SDK-AM64X
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hi,

While integrating OSPI NOR Flash from Macronix, customers have faced flash errors.

Here are the top two concerns faced:

  1. The most common error being: The OSPI Controller fails to read the Flash's manufacture and device id.
  2. The second one being not able to operate in 8D-8D-8D and read and write from/to the flash after Step 1 problem is resolved.

Let us understand how to go about debugging this in detail.

NOTE:

We do not support Macronix flash part on TI EVMs from Software point of view, but it can be integrated. The following is a result of few customer debugs, which can help you move forward if you are planning to use a Macronix flash part.

  • Background:

    Macronix is big endian and our system is little endian. Controller doesn't provide a way to swap this. This is not a issue if we always stick to 8d-8d-8d mode for all data operations. But the moment you will try mixed mode, this will hurt.

    For example, if we write in 1S-1S-1S and try to read back in 8D-8D-8D, then this is the behaviour which has been observed.

    If we write the data 10, 11, 12, 13 in 1S-1S-1S mode, and try to read back in 8D-8D-8D mode, then byte swapping happens, and the data which is fetched is basically 11, 10, 13, 12. This is not a fault of our controller, but a property of Macronix flash part(being Big Endian) and our System(being Little Endian) that causes this indifference.

    To eliminate this, we got to make sure that, all the operations are happening in just one single mode, so for example, either do all the operations from ROM-> Bootloader-> Application in 1S-1S-1S mode, or all of them in 8D-8D-8D mode.

    FYI, I want to highlight one section from AM64x TRM(or one of our Sitara SoC's TRM):

    This allows the ROM to start in 1S-1S-1S and then switch to 8D-8D-8D when the SFDP bit in enabled. This makes sure that you can have the rest of the flash operations at bootloader and application level in 8D-8D-8D mode which is much faster than just sticking to 1S-1S-1S mode for all the operations.

  • Exceptions:

    Few Macronix flash parts can swap the byte by itself when reading back in 8D-8D-8D. For example: MX66UW2G345G is new Macronix Octal Flash EPN that can swap byte when reading in Octal DDR mode.

    In this case, the Controller need not swap the byte and can run in mixed mode, for example, ROM boots in 1S-1S-1S mode and then the bootloader and application has 8D-8D-8D mode of operations. 

    But, this is something to be checked with the flash vendor if the flash part they are going ahead with supports this byte swapping logic or not. If not, then we must stick to one mode of operation across all levels, else we can have mixed mode of operations.

  • Assuming the flash configurations are set correctly in SysConfig using the following guide, we can proceed further.

    The most common error being: The OSPI Controller fails to read the Flash's manufacture and device id.

    This happens due to the following reason.

    If you read through the Macronix's Flash part datasheet, for reading the manufacture id and device id the most commonly used command is 0x9Fh.

    In the table it is sometimes mentioned that while sending this command 0x9Fh, 0x60h(an inverse of 0x9Fh), the read values from the Flash will be output in STR mode.

    It is commonly mentioned under NOTE 6 as shown below.

    This means if the Manufacture and Device ID is 0xC2 and 0x8138 respectively, then ideally it would have been read back as [0xC2, 0x81, 0x38] in the recieve buffer, but since the data bytes are output in STR mode, hence in receive buffer we get the data in the following format: [0xC2, 0xC2, 0x81, 0x81, 0x38, 0x38]


    This calls for a bit of change in how we interpret the incoming data.

    So in the file, flash_nor_ospi.c, there is an API which reads back the data. The name is: Flash_norOspiReadId()

    I have pasted a snippet of a code from this API below:

        status = Flash_norOspiCmdRead(config, idCfg->cmd, cmdAddr, numAddrBytes, dummyBits, idCode, idNumBytes);
    
        /* Verify ID with filled data */
        if (status == SystemP_SUCCESS)
        {
            uint32_t manfID, devID;
    
            manfID = (uint32_t)idCode[0];
            devID = ((uint32_t)idCode[1] << 8) | ((uint32_t)idCode[2]);

    So here we need to change few things, like the parameters idNumBytes and the way we interpret the data, as we will receive 6 values as mentioned above: [0xC2, 0xC2, 0x81, 0x81, 0x38, 0x38]

    So the new snippet would like like:

        idNumBytes = 6; // because we read back 6 bytes for Macronix Flash part since Data is output in STR mode
        
        status = Flash_norOspiCmdRead(config, idCfg->cmd, cmdAddr, numAddrBytes, dummyBits, idCode, idNumBytes);
    
        /* Verify ID with filled data */
        if (status == SystemP_SUCCESS)
        {
            uint32_t manfID, devID;
            
            // indexes change here as 0xC2 comes on 0th index, 0x81 comes on 2nd index and 0x38 comes on 4th index
            
            manfID = (uint32_t)idCode[0];
            devID = ((uint32_t)idCode[2] << 8) | ((uint32_t)idCode[4]);

    These changes should be enough to read the flash manufacture and device id.

  • The second one being not able to operate in 8D-8D-8D and read and write from/to the flash after Step 1 problem is resolved.

    The reasoning for this is covered in the Background section.