Skip to main content
Visitor II
August 1, 2024
Question

driver for external SRAM chip - IS66WVS4M8ALL/BLL

  • August 1, 2024
  • 3 replies
  • 1722 views

Hi, I'm trying to add an external memory and i choose that chip because it can communicate with QSPI and there is no need for designing due the chip is SOIC-8 which i found a compatible board for it. 

I'm getting issues with the driver writing i'm getting all the time a hard fault or infinite loop. i use chatGPT for the driver writing because i didn't found any written one.

My QUADSPI configuration:

Ditzhak_0-1722495083492.png

This is the driver:

'''c

 HAL_StatusTypeDef QSPI_EnterQPI(QSPI_HandleTypeDef *hqspi)

{

QSPI_CommandTypeDef s_command;

uint8_t reg = 0x35;

 

s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;

s_command.Instruction = reg;

s_command.AddressMode = QSPI_ADDRESS_NONE;

s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

s_command.DdrMode = QSPI_DDR_MODE_DISABLE;

s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

s_command.DataMode = QSPI_DATA_NONE;

s_command.DummyCycles = 0;

 

if (HAL_QSPI_Command(hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

printf("Error: Enter QPI Mode Failed\n");

return HAL_ERROR;

}

printf("Entered QPI Mode Successfully\n");

return HAL_OK;

}

 

 

 

 

 

HAL_StatusTypeDef QSPI_ExitQPI(QSPI_HandleTypeDef *hqspi)

{

QSPI_CommandTypeDef s_command;

uint8_t reg = 0xF5;

 

s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;

s_command.Instruction = reg;

s_command.AddressMode = QSPI_ADDRESS_NONE;

s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

s_command.DdrMode = QSPI_DDR_MODE_DISABLE;

s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

s_command.DataMode = QSPI_DATA_NONE;

s_command.DummyCycles = 0;

 

if (HAL_QSPI_Command(hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

printf("Error: Exit QPI Mode Failed\n");

return HAL_ERROR;

}

printf("Exited QPI Mode Successfully\n");

return HAL_OK;

 

}

 

HAL_StatusTypeDef QSPI_Write(QSPI_HandleTypeDef *hqspi, uint32_t address, uint8_t *data, uint16_t size)

{

QSPI_CommandTypeDef s_command;

 

s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;

s_command.Instruction = 0x38;

s_command.AddressMode = QSPI_ADDRESS_4_LINES;

s_command.Address = address;

s_command.AddressSize = QSPI_ADDRESS_24_BITS;

s_command.DataMode = QSPI_DATA_4_LINES;

s_command.NbData = size;

s_command.DummyCycles = 0;

s_command.DdrMode = QSPI_DDR_MODE_DISABLE;

s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

 

if (HAL_QSPI_Command(hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

printf("Error: QSPI Write Command Failed\n");

return HAL_ERROR;

}

 

if (HAL_QSPI_Transmit(hqspi, data, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

printf("Error: QSPI Write Transmit Failed\n");

return HAL_ERROR;

}

 

printf("QSPI Write to Address 0x%08lX Successfully\n", address);

return HAL_OK;

}

 

HAL_StatusTypeDef QSPI_Read(QSPI_HandleTypeDef *hqspi, uint32_t address, uint8_t *data, uint16_t size)

{

QSPI_CommandTypeDef s_command;

 

s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;

s_command.Instruction = 0xEB;

s_command.AddressMode = QSPI_ADDRESS_4_LINES;

s_command.Address = address;

s_command.AddressSize = QSPI_ADDRESS_24_BITS;

s_command.DataMode = QSPI_DATA_4_LINES;

s_command.NbData = size;

s_command.DummyCycles = 6; // Based on datasheet requirement

s_command.DdrMode = QSPI_DDR_MODE_DISABLE;

s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

 

if (HAL_QSPI_Command(hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

printf("Error: QSPI Read Command Failed\n");

return HAL_ERROR;

}

 

if (HAL_QSPI_Receive(hqspi, data, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

printf("Error: QSPI Read Receive Failed\n");

return HAL_ERROR;

}

 

printf("QSPI Read from Address 0x%08lX Successfully\n", address);

return HAL_OK;

}

 

 

static HAL_StatusTypeDef QSPI_WaitForWriteComplete(QSPI_HandleTypeDef *hqspi)

{

QSPI_CommandTypeDef s_command;

uint8_t reg;

uint8_t status;

 

s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;

s_command.Instruction = 0x05;

s_command.AddressMode = QSPI_ADDRESS_NONE;

s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

s_command.DdrMode = QSPI_DDR_MODE_DISABLE;

s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

s_command.DataMode = QSPI_DATA_4_LINES;

s_command.NbData = 1;

s_command.DummyCycles = 0;

 

printf("Waiting for Write to Complete...\n");

do {

if (HAL_QSPI_Command(hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

printf("Error: QSPI Read Status Command Failed\n");

return HAL_ERROR;

}

 

if (HAL_QSPI_Receive(hqspi, &status, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

printf("Error: QSPI Read Status Receive Failed\n");

return HAL_ERROR;

}

} while (status & 0x01);

 

printf("Write Complete\n");

return HAL_OK;

}

 

static HAL_StatusTypeDef QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)

{

QSPI_CommandTypeDef s_command;

 

s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;

s_command.Instruction = 0x06;

s_command.AddressMode = QSPI_ADDRESS_NONE;

s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

s_command.DdrMode = QSPI_DDR_MODE_DISABLE;

s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

s_command.DataMode = QSPI_DATA_NONE;

s_command.DummyCycles = 0;

 

if (HAL_QSPI_Command(hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {

printf("Error: QSPI Write Enable Command Failed\n");

return HAL_ERROR;

}

 

printf("Write Enable Command Sent Successfully\n");

return HAL_OK;

}

When i'm getting into HAL_StatusTypeDef QSPI_EnterQPI(QSPI_HandleTypeDef *hqspi) function 

i get stuck in this function:

static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,

FlagStatus State, uint32_t Tickstart, uint32_t Timeout)

{

/* Wait until flag is in expected state */

while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)

{

/* Check for the Timeout */

if (Timeout != HAL_MAX_DELAY)

{

if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))

{

hqspi->State = HAL_QSPI_STATE_ERROR;

hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;

 

return HAL_ERROR;

}

}

}

return HAL_OK;

} '''

 

 

which i don't understand why

 

Someone can help me?

    This topic has been closed for replies.

    3 replies

    Technical Moderator
    August 2, 2024

    Hello @Ditzhak ,

     

    Could you please take a look at this FAQ How to debug a HardFault on an Arm Cortex®-M STM32 may help you to debug the HardFault.

    Also, I advise you to refer to this post "Solved: STM32U5A5: PSRAM (4MB external RAM) via QSPI (OCTO... - STMicroelectronics Community"  and check the OCTOSPI configuration (the chip used : IS66WVS4M8ALL) and AN5050.

    Thank you.

    Kaouthar 

    Graduate II
    August 2, 2024

    Please use the </> code formatter to post code, please edit your post and fix

    You have to Memory Map the QSPI for it to be able to access memory at 0x90000000, otherwise you'll get Hard Faults if you touch it.

    ChatGPT is not paid to do the job of the Embedded Software Engineer, you might want to read the manuals to understand how things actually work..

    Super User
    August 2, 2024

    Which STM32H7? Does it have Octo-SPI or only QSPI?

    DitzhakAuthor
    Visitor II
    August 4, 2024

    STM32H753 - have only QSPI

    Super User
    August 4, 2024

    QSPI cannot write in memory mapped mode, as you probably know.