Skip to main content
Associate II
September 6, 2024
Solved

Write in OSPI

  • September 6, 2024
  • 2 replies
  • 1858 views

Hello,

I'm working on STM32H7B3I-EVAL with STM32CubeIDE. I would like to write in the OSPI, so I made the following code:

void OSPI_Write(uint32_t address, uint8_t *data, uint32_t size) {
OSPI_RegularCmdTypeDef sCommand;

// Désactivation du mode mappé
HAL_OSPI_Abort(&hospi1);


// Configuration de la commande pour l'écriture en mode indirect
sCommand.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.Instruction = MX25LM51245G_OCTA_WRITE_ENABLE_CMD;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.Address = address;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.NbData = size;
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;


// Envoye de la commande d'écriture
if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { //5s
Error_Handler();
}

// Écrire les données dans la mémoire
if (HAL_OSPI_Transmit(&hospi1, data, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
Error_Handler();
}

// Attendre que l'opération soit terminée
OSPI_AutoPollingMemReady(&hospi1);
}


void OSPI_AutoPollingMemReady(OSPI_HandleTypeDef *hospi) {
OSPI_AutoPollingTypeDef sConfig;

// Configuration pour la lecture du statut de la mémoire pour vérifier si elle est prête
sConfig.Match = 0x00;
sConfig.Mask = 0x01;
sConfig.MatchMode = HAL_OSPI_MATCH_MODE_AND;
sConfig.Interval = 0x10;
sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE;

OSPI_RegularCmdTypeDef sCommand;
sCommand.Instruction = 0x05;
sCommand.InstructionMode= HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.NbData = 1;

HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
HAL_OSPI_AutoPolling(hospi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
}

Sorry the comments are in french.

The problem is that it can't write to the OSPI, on the first if it does Error_Handler.

Could you please help me to understand where the error comes from?

 

Best answer by Tesla DeLorean

>>I still get the same thing

That's not helpful.  Which part is failing, what line, what error? Make sure the setting passed are consistent with the mode the memory is in. You can't randomly mix-n-match. If you're going to cut-n-paste code you're going to have to pay attention to ALL the details for it to have some chance of working.

The Write Enable has no address or data component

 

    sCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
    sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
 
    sCommand.AddressMode        = HAL_OSPI_ADDRESS_NONE;
    sCommand.DataMode           = HAL_OSPI_DATA_NONE;
    sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
 
    sCommand.Instruction        = MX25LM51245G_WRITE_ENABLE_CMD;
    sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE; // SPI 
    sCommand.InstructionSize =  HAL_OSPI_INSTRUCTION_8_BITS;
or
    sCommand.Instruction        = MX25LM51245G_OCTA_WRITE_ENABLE_CMD;
    sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES; // OCTO MODE
    sCommand.InstructionSize =  HAL_OSPI_INSTRUCTION_16_BITS;
 
 
I could code an entire worked example, but they'd need to be some value to that as it would take time/effort.

2 replies

TDK
Super User
September 6, 2024

Where does Error_Handler get called? Look at the call stack and go back to see where/why it's called and correct. Step through the functions to see where it bails out.

"If you feel a post has answered your question, please click ""Accept as Solution""."
rozeelcAuthor
Associate II
September 6, 2024

Thank you for your reply

it is called here ”

if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { Error_Handler();
}"

Except that normally, if it's written properly, it's not supposed to call Error_Handler.

I don't understand why it can't write.

TDK
Super User
September 6, 2024

Step into that function and step line by line and see where it exits. Don't treat it as a black box. Probably something in the sCommand structure is invalid or hospi1 state is not as expected.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Tesla DeLorean
Guru
September 6, 2024

OSPI_RegularCmdTypeDef sCommand = {0}; // Clear the auto variables for consistency of usage

Step 1 : Write Enable, just the Command

Step 2 :Page Program, with the Address / Data

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
rozeelcAuthor
Associate II
September 6, 2024

Thanks for your help.

I modified my code like this :

 
void OSPI_Write(uint32_t address, uint8_t *data, uint32_t size) {
OSPI_RegularCmdTypeDef sCommand = {0};
 
    // Désactivation du mode mappé
    HAL_OSPI_Abort(&hospi1);
 
    // --- Étape 1 : Activer l'écriture (Write Enable) --
    sCommand.OperationType      = HAL_OSPI_OPTYPE_WRITE_CFG;
    sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
    sCommand.Instruction        = MX25LM51245G_OCTA_WRITE_ENABLE_CMD;
    sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES;
    sCommand.AddressMode        = HAL_OSPI_ADDRESS_8_LINES;
    sCommand.DataMode           = HAL_OSPI_DATA_8_LINES;
    sCommand.DummyCycles        = 0;
 
 
    // Envoye de la commande d'écriture
    if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {  //5s
        Error_Handler();
    }
 
    // --- Étape 2 : Programmer la page ---
    // Configuration de la commande pour l'écriture en mode indirect
   sCommand.Instruction     = MX25LM51245G_OCTA_PAGE_PROG_CMD;
   sCommand.AddressMode     = HAL_OSPI_ADDRESS_8_LINES;
   sCommand.AddressSize     = HAL_OSPI_ADDRESS_32_BITS;
   sCommand.Address         = address;
   sCommand.DataMode        = HAL_OSPI_DATA_8_LINES;
   sCommand.NbData          = size;
   sCommand.DummyCycles     = 0;
   sCommand.DQSMode         = HAL_OSPI_DQS_DISABLE;
 
   // Envoyer la commande de programmation
   if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
       Error_Handler();
   }
 
// Écrire les données dans la mémoire
    if (HAL_OSPI_Transmit(&hospi1, data, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
        Error_Handler();
    }
 
    // Attendre que l'opération soit terminée
    OSPI_AutoPollingMemReady(&hospi1);
}
 
 
void OSPI_AutoPollingMemReady(OSPI_HandleTypeDef *hospi) {
    OSPI_AutoPollingTypeDef sConfig;
 
    // Configuration pour la lecture du statut de la mémoire pour vérifier si elle est prête
    sConfig.Match           = 0x00;
    sConfig.Mask            = 0x01;
    sConfig.MatchMode       = HAL_OSPI_MATCH_MODE_AND;
    sConfig.Interval        = 0x10;
    sConfig.AutomaticStop   = HAL_OSPI_AUTOMATIC_STOP_ENABLE;
 
    OSPI_RegularCmdTypeDef sCommand;
    sCommand.Instruction    = 0x05;
    sCommand.InstructionMode= HAL_OSPI_INSTRUCTION_8_LINES;
    sCommand.AddressMode    = HAL_OSPI_ADDRESS_NONE;
    sCommand.DataMode       = HAL_OSPI_DATA_8_LINES;
    sCommand.NbData         = 1;
 
    HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
    HAL_OSPI_AutoPolling(hospi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
}

I still get the same thing.

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
September 6, 2024

>>I still get the same thing

That's not helpful.  Which part is failing, what line, what error? Make sure the setting passed are consistent with the mode the memory is in. You can't randomly mix-n-match. If you're going to cut-n-paste code you're going to have to pay attention to ALL the details for it to have some chance of working.

The Write Enable has no address or data component

 

    sCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
    sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
 
    sCommand.AddressMode        = HAL_OSPI_ADDRESS_NONE;
    sCommand.DataMode           = HAL_OSPI_DATA_NONE;
    sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
 
    sCommand.Instruction        = MX25LM51245G_WRITE_ENABLE_CMD;
    sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE; // SPI 
    sCommand.InstructionSize =  HAL_OSPI_INSTRUCTION_8_BITS;
or
    sCommand.Instruction        = MX25LM51245G_OCTA_WRITE_ENABLE_CMD;
    sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES; // OCTO MODE
    sCommand.InstructionSize =  HAL_OSPI_INSTRUCTION_16_BITS;
 
 
I could code an entire worked example, but they'd need to be some value to that as it would take time/effort.
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..