Skip to main content
Visitor 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?

 

    This topic has been closed for replies.
    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

    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.

    rozeelcAuthor
    Visitor 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.

    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.

    Graduate II
    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

    rozeelcAuthor
    Visitor 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.

    Graduate II
    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.