cancel
Showing results for 
Search instead for 
Did you mean: 

driver for external SRAM chip - IS66WVS4M8ALL/BLL

Ditzhak
Associate III

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?

5 REPLIES 5
KDJEM.1
ST Employee

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 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

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

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

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

STM32H753 - have only QSPI

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