cancel
Showing results for 
Search instead for 
Did you mean: 

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

sohm
Associate III

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!

12 REPLIES 12
Sanath
Associate II

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

 

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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