Skip to main content
Visitor II
November 21, 2024
Question

Issue with RWW Configuration Using OSPI1 and OSPI2 on STM32U5A9J-DK

  • November 21, 2024
  • 5 replies
  • 2569 views

Hi,

We are using the STM32U5A9J-DK board and are trying to achieve Read-While-Write (RWW) functionality. The flash chip we are using supports RWW.

Earlier, as per [this post](post link), we learned that to achieve RWW, we need two OSPI instances, namely OSPI1 and OSPI2.

Here are the configurations for both OSPI1 and OSPI2 in STM32CubeIDE:

  • OSPI1 Configuration:
    OSPI1.png

  • OSPI2 Configuration: 

    OSPI2.png


We tested the setup and observed the following:

  1. Using OSPI1, we can successfully perform read, write, and erase operations on the flash memory.
  2. However, when attempting to access the flash memory with OSPI2, we are unable to perform these operations.

Questions:

  1. Is our current configuration of OSPI1 and OSPI2 (in multiplexed mode) correct for achieving RWW?
  2. Can you provide an example application where RWW is implemented using OSPI1 and OSPI2?

We would greatly appreciate any insights or guidance on this issue.

Thank you!

    This topic has been closed for replies.

    5 replies

    Technical Moderator
    November 21, 2024

    Hello @sohm ,

     

    Thank you for sharing this interesting case in the community.

    However, when attempting to access the flash memory with OSPI2, we are unable to perform these operations.

    ->The Chip select pin is not configured for the OCTOSPI2 in OSPI2 configuration.

    Is the issue solved when configuring the "Chip Select".

    An RWW example is available in  https://github.com/STMicroelectronics/STM32CubeH7RS/tree/main/Projects/STM32H7S78-DK/Examples/XSPI/XSPI_NOR_ReadWhileWrite_DTR.

    May be STM32CubeMX: OCTOSPI GPIOs configuration section in AN5050 can help you.

     

    Thank you.

    Kaouthar

     

    sohmAuthor
    Visitor II
    November 22, 2024

    Hi @KDJEM.1 

     

    Thank you for your response and the suggestions provided.

    Unfortunately, the issue is not resolved after configuring the chip select for OSPI2.

    Chip_select.png

    As per the schematic, the flash's chip select is connected to PORT1. When we configure the chip select option in OSPI2 as PORT1 NCS, we must disable it in OSPI1. In this scenario:

    • We can access the flash using the OSPI2 instance, but OSPI1 access stops working.
    • Similarly, when OSPI1 is enabled, OSPI2 access fails.

    This means we can access the flash using either OSPI1 or OSPI2, but not both simultaneously. Since RWW functionality requires both instances to work concurrently, we are facing a roadblock.

    The example you shared is for a different development board. We tried replicating the configurations on our platform (STM32U5A9J-DK) but still cannot access the flash with both OSPI1 and OSPI2 instances simultaneously.


    We suspect that we may be missing something in the configuration.

    Could you confirm whether our current configuration aligns with the requirements for RWW? Additionally, is there any application project or reference specifically for STM32U5A9J-DK where RWW has been demonstrated to work?

    Our octal SPI nor flash memory supports RWW. Can you confirm  the STM32U5A9J-DK supports RWW ?

    We appreciate your guidance and support in resolving this issue.

    Technical Moderator
    November 22, 2024

    Hello @sohm ,

     

    As I mentioned in this post, the read while write mode needs a memory supported the RWW (have two bank), two OCTOSPIs interface (OCTOSPI1 and OCTOSPI2), OCTOSPI I/O manager. 

    The MX25UM51245G memory mounted on STM32U5A9J-DK doesn't support (RWW) the multi-bank like as MX66UW1G45G memory supports XIP and RWW (Read-While-Write) due to its multi-bank structure, which allows reading data from one bank while another bank is being programmed or erased.

    Please take a look at  MX25UM51245G and MX66UW1G45G datasheets.

    Thank you.

    Kaouthar

     

    sohmAuthor
    Visitor II
    November 25, 2024

    Hi @KDJEM.1 ,

    Thank you for your response.

    As mentioned, we understand that RWW needs to be supported by the Octal SPI NOR flash memory, which is true in our case. We are using ISSI Octal Flash Memory that supports RWW. We have connected the ISSI flash memory in place of the Macronix flash on the STM32U5A9J-DK as shown in the attached image.

    Pic2.png

    The RWW example provided by you is for the STM32H7S78-DK, which uses an xSPI IO Manager. However, our board (STM32U5A9J-DK) is equipped with an OSPI IO Manager.

    Referring to the AN5050 (page 25):

    • The xSPI IO Manager delivers one NCS signal along with a CSSEL control signal.
    • It also allows selecting the same NCS for both XSPI_1 and XSPI_2 using the configuration.

      pic1.png

    XSPI Configurations for RWW example that you have given :

    • hxspi1.Init.MemorySelect = HAL_XSPI_CSSEL_NCS1;
      hxspi2.Init.MemorySelect = HAL_XSPI_CSSEL_NCS1;

      sXspiManagerCfg.nCSOverride = HAL_XSPI_CSSEL_OVR_NCS1;

    However, the OSPI IO Manager does not provide these options:

    • When selecting Port1 NCS for OSPI1, it does not allow the same Port1 NCS for OSPI2.
    • Instead, we either need to disable Port1 NCS for OSPI2 or switch to Port2 NCS.

    As a result:

    • If OSPI1 is configured to use Port1 NCS, OSPI2 stops working.
    • Similarly, if OSPI2 is configured to use Port1 NCS, OSPI1 stops working.

    This limitation seems to make it impossible to access the ISSI flash memory from both OSPI1 and OSPI2 instances simultaneously in multiplexed mode using the OSPI IO Manager.

    Could you please confirm whether our understanding is correct?


    Thank You .

    sohmAuthor
    Visitor II
    November 26, 2024

    Hi @KDJEM.1 , 

     

    Can you please reply on our query in the previous post. This is really important for us to move forward in our current project. We are kind of blocked and want your confirmation. 

    If RWW is not possible by using multiplexed mode (by using both OSPI1 and OPSI2) , is there any other way to do RWW on STM32U5A9J-DK.

     

     

    Thank You.

    Technical Moderator
    November 27, 2024

    Hello @sohm

     

    For my part, I have not found an RWW example with the STM32U5A9 device for the moment.

    Could you please give more information about your use case? Is the firmware upgrade?

    Maybe you can use two memories configured separately, not in multiplexed mode.

    Could you try to configure OCTOSPI1 and the OCTSPI2 in multiplexed mode with the same chip select manually with software without using STM32CubeMX?

    Let me know if the issue is solved or not.

     

    Thank you.

    Kaouthar

    Explorer II
    December 3, 2024

    Hi @KDJEM.1 

     

    Sorry for the delayed response.

    We are able to Read and Write by controlling the  Chipselect in Software in Multiplexmode. Now we are trying to do RWW where we are trying to Write Using OSPI2 and Read using OSPI1 DMA .

     

    Any specific Inputs on this? Do we need any changes in OSPI drivers to achieve this? 

     

    Sanath

     

    Technical Moderator
    December 3, 2024

    Hello @Sanath,

     

    Thank you for updating this post.

    Could you please give more information about your use case? Is the firmware upgrade?

    On my side, I do not found any specific inputs or any change in OSPI driver to write using OSPI2 and read using OSPI1 DMA.

     

    Thank you.

    Kaouthar

    Explorer II
    December 3, 2024

    @KDJEM.1 

     

    Our Requirement is to achieve the RWW for our Flash chip which has RWW capability

    Our Use case is to Write to Particular Bank(We have 4 Banks)

    And while writing we need to read from another Bank.

    Regards,

    Sanath

    Explorer II
    December 8, 2024

    Hi @KDJEM.1 

     

    We are able to do the RWW operation by controlling the CS in software in multiplex mode .

    I am able to write to a bank and at the same time able to read the data from another bank.

     

    But there is one thing i need to read the BANKSTAT register to display the error handling and operations going on particular banks.

     

    below is my code for doing that .But i am unable to read the stat register.

    I am using READ VOLATILE REGISTER command and address command 0x11 of BANKSTAT to do it can you please tell me whats the issue in below code

     

    int ospi_check_RWW_Read(RWWContext_t RWWContext)
    {

        uint8_t bankSTATOffset  = 4;
        uint8_t bankSTATMask    = 0x07;
        uint8_t rxBuff          = 0;
        OSPI_RegularCmdTypeDef sCommand;

        // Step 1: Configure the command to read the volatile register
        sCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
        sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
        sCommand.Instruction        = READ_VOLATILE_CONFIG_REG;         //0x85  Read Volatile Register command
        sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE;
        sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;
        sCommand.AddressMode        = HAL_OSPI_ADDRESS_1_LINE;
        sCommand.AddressSize        = HAL_OSPI_ADDRESS_32_BITS;
        sCommand.Address            = READ_BANKSTAT_ADDRESS;  //0x11
        sCommand.DataMode           = HAL_OSPI_DATA_1_LINE;
        sCommand.NbData             = 1;
        sCommand.DummyCycles        = 8;
        sCommand.DQSMode            = HAL_OSPI_DQS_DISABLE;
        sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;
        sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

        sCommand.AddressDtrMode     = HAL_OSPI_ADDRESS_DTR_DISABLE;
        sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
        sCommand.DataDtrMode        = HAL_OSPI_DATA_DTR_DISABLE;

        HAL_GPIO_WritePin(CS_OSPI_GPIO_Port, CS_OSPI_Pin, GPIO_PIN_RESET);

        // Step 2: Send read command
        if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
            Error_Handler();  // Ensure Error_Handler() provides feedback for debugging
        }

        // Step 3: Receive the register data
        if (HAL_OSPI_Receive(&hospi1, &rxBuff, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
            Error_Handler();  // Ensure Error_Handler() provides feedback for debugging
        }


        printf ("The readValue is %x\r\n", rxBuff);
     

        RWWContext.WriteBANK = rxBuff;
        switch (RWWContext.BANKSize)
        {

        case BANK_4_ARCHITECTURE:  bankSTATMask = BANKSTST_REGISTER_MASK_4_BANK_SIZE;
        break;
        case BANK_8_ARCHITECTURE:  bankSTATMask = BANKSTST_REGISTER_MASK_8_BANK_SIZE;
        break;
        case BANK_16_ARCHITECTURE: bankSTATMask = BANKSTST_REGISTER_MASK_16_BANK_SIZE;
        break;
        default: break;
        }

        if( ( rxBuff & bankSTATMask) != 0)
        {
            //printf ("The rxBuff 0x%x\r\n",rxBuff );
            return RWWonGoingWriteError;
        }

        HAL_GPIO_WritePin(CS_OSPI_GPIO_Port, CS_OSPI_Pin, GPIO_PIN_SET);
        return SUCCESS;

    }
     
     
    Sanath

     

    Graduate II
    December 8, 2024

    Probably also want to fix the exit paths so CS goes HIGH, even when unsuccessful

    Explorer II
    December 13, 2024

    Hi @Tesla DeLorean ,

     

    Have tried giving exit paths also by giving CS HIGH still unable to read the BANK STAT.Dont know what we are missing.

     

    The Datasheet says First we need to send Command 0x85(READ VOLATILE REG) then the Address of BANK STAT(0x11) followed by dummy cycles (8)  then we need to read the DATA,But unable to do it?

     

    Below  is the API 

    uint8_t bankSTATOffset = 4;

    uint8_t bankSTATMask = 0x07;

    uint8_t bankStatus = 0;

    //uint8_t readValue [2] = {0};

    OSPI_RegularCmdTypeDef sCommand;

     

    // Step 1: Configure the command to read the volatile register

    sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;

    sCommand.FlashId = HAL_OSPI_FLASH_ID_1;

    sCommand.Instruction = READ_VOLATILE_CONFIG_REG;//(0x85) // Read Volatile Register command

    sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;

    sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;

    sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;

    sCommand.AddressSize = HAL_OSPI_ADDRESS_8_BITS;

    sCommand.Address = READ_BANKSTAT_ADDRESS;//(0x11)

    sCommand.DataMode = HAL_OSPI_DATA_1_LINE;

    sCommand.NbData = 1;

    sCommand.DummyCycles = 8;

    sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;

    sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;

    sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

     

    sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;

    sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;

    sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;

     

    HAL_GPIO_WritePin(CS_OSPI_GPIO_Port, CS_OSPI_Pin, GPIO_PIN_RESET);

    // Step 2: Send read command

    if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

    HAL_GPIO_WritePin(CS_OSPI_GPIO_Port, CS_OSPI_Pin, GPIO_PIN_SET);

    Error_Handler(); // Ensure Error_Handler() provides feedback for debugging

    }

     

    if (HAL_OSPI_Receive_DMA(&hospi1, &rxBuff) != HAL_OK)

    {

    HAL_GPIO_WritePin(CS_OSPI_GPIO_Port, CS_OSPI_Pin, GPIO_PIN_SET);

    Error_Handler(); // DMA transfer failed

    }

     

    HAL_GPIO_WritePin(CS_OSPI_GPIO_Port, CS_OSPI_Pin, GPIO_PIN_SET);

    //printf ("The readValue is %x \r\n", rxBuff);

     

    //DebugP_log("RWW write status :0x%X\r\n",rxBuff);

    //DebugP_log("RWWContext.BankSize :0x%X\r\n",RWWContext.BANKSize);

     

    #if 1

    RWWContext.WriteBANK = rxBuff;

    switch (RWWContext.BANKSize)

    {

     

    case BANK_4_ARCHITECTURE: bankSTATMask = BANKSTST_REGISTER_MASK_4_BANK_SIZE;

    break;

    case BANK_8_ARCHITECTURE: bankSTATMask = BANKSTST_REGISTER_MASK_8_BANK_SIZE;

    break;

    case BANK_16_ARCHITECTURE: bankSTATMask = BANKSTST_REGISTER_MASK_16_BANK_SIZE;

    break;

    default: break;

    }

    bankStatus = rxBuff & bankSTATMask;

    //DebugP_log("RWW write status :0x%X\r\n",rxBuff);

    // printf ("The rxBuff 0x%x\r\n",rxBuff );

    // printf("Bank Status: %d\r\n", bankStatus);

     

    // if( ( rxBuff & bankSTATMask) != 0)

    // {

    // //printf ("The rxBuff 0x%x\r\n",rxBuff );

    // return RWWonGoingWriteError;

    // }

     

    #endif

    return SUCCESS;

     

    @KDJEM.1 

    One more observation we have is when we do write for Bank 0 in RWW operation whose

    sector is from 0-63 we are seeing its effecting even 64th sector the content is being

    written to it as well. Similarly, when written to BANK1 and BANK 2, it's getting

    effected to BANK2 and BANK3 Respectively. Its only happening to adjacent Banks first sector only.Remaining its not effecting.

    How to tackle this?

     

    Regards,

    Sanath