cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with integration of W25Q128JV on STM32U5A9

Edward_1583
Associate II

I'm working on a project where I use the STM32U5A9 microcontroller to control the W25Q128JV flash memory. I wrote a library to interact with this flash memory, but unfortunately I can't get it set up correctly.

The problem is that commands are sent incorrectly when this piece of code in the enableQuadMode function is executed:

 

 CS_ENABLE();



OSPI_RegularCmdTypeDef sCommand = {0};

uint8_t reg;

HAL_StatusTypeDef res;



sCommand.OperationType = READ_STATUS_REG_CMD;

sCommand.FlashId = HAL_OSPI_FLASH_ID_1;

sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;

sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;

sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;

sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;

sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;

sCommand.Instruction = READ_STATUS_REG2_CMD;

sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;

sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

sCommand.DataMode = HAL_OSPI_DATA_NONE;

sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;

sCommand.DummyCycles = 0;

sCommand.NbData = 1;



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}

 

the logic analyzer displays this:

Edward_1583_0-1720183493377.png

Maybe any of you have faced a similar problem or can suggest some steps to solve it? Any help or guidance would be greatly appreciated!

Thanks in advance!

Settings OCTOSPI:

 

void MX_OCTOSPI1_Init(void)

{



/* USER CODE BEGIN OCTOSPI1_Init 0 */



/* USER CODE END OCTOSPI1_Init 0 */



OSPIM_CfgTypeDef sOspiManagerCfg = {0};

 HAL_OSPI_DLYB_CfgTypeDef HAL_OSPI_DLYB_Cfg_Struct = {0};



/* USER CODE BEGIN OCTOSPI1_Init 1 */



/* USER CODE END OCTOSPI1_Init 1 */

 hospi1.Instance = OCTOSPI1;

 hospi1.Init.FifoThreshold = 1;

 hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;

 hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;

 hospi1.Init.DeviceSize = 24;

 hospi1.Init.ChipSelectHighTime = 1;

 hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;

 hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;

 hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;

 hospi1.Init.ClockPrescaler = 64-1;

 hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;

 hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;

 hospi1.Init.ChipSelectBoundary = 0;

 hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;

 hospi1.Init.MaxTran = 0;

 hospi1.Init.Refresh = 0;

if (HAL_OSPI_Init(&hospi1) != HAL_OK)

{

Error_Handler();

}

sOspiManagerCfg.ClkPort = 1;

sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;

sOspiManagerCfg.Req2AckTime = 1;

if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

{

Error_Handler();

}

HAL_OSPI_DLYB_Cfg_Struct.Units = 0;

HAL_OSPI_DLYB_Cfg_Struct.PhaseSel = 0;

if (HAL_OSPI_DLYB_SetConfig(&hospi1, &HAL_OSPI_DLYB_Cfg_Struct) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN OCTOSPI1_Init 2 */



/* USER CODE END OCTOSPI1_Init 2 */



}

 


My code:

 

/*

 * external_flash_driver.c

 *

 * Created on: Jun 11, 2024

 * Author: nhrabets

 */



#include "main.h"



#include "octospi.h"



#include "external_flash_driver.h"





#define CS_ENABLE() HAL_GPIO_WritePin(QSPI_CS_GPIO_Port, QSPI_CS_Pin, 0)

#define CS_DISABLE() HAL_GPIO_WritePin(QSPI_CS_GPIO_Port, QSPI_CS_Pin, 1)





static uint8_t writeEnable(void)

{

 CS_ENABLE();



OSPI_RegularCmdTypeDef sCommand = {0};

OSPI_AutoPollingTypeDef sConfig = {0};

HAL_StatusTypeDef res;



sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;

sCommand.FlashId = HAL_OSPI_FLASH_ID_1;

sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;

sCommand.Instruction = WRITE_ENABLE_CMD;

sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;

sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;

sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;

sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

sCommand.DataMode = HAL_OSPI_DATA_NONE;

sCommand.DummyCycles = 0;

sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;

sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



 CS_DISABLE();



return HAL_OK;



}



static uint8_t enableQuadMode(void)

{

 CS_ENABLE();



OSPI_RegularCmdTypeDef sCommand = {0};

uint8_t reg;

HAL_StatusTypeDef res;



sCommand.OperationType = READ_STATUS_REG_CMD;

sCommand.FlashId = HAL_OSPI_FLASH_ID_1;

sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;

sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;

sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;

sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;

sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;

sCommand.Instruction = READ_STATUS_REG2_CMD;

sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;

sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

sCommand.DataMode = HAL_OSPI_DATA_NONE;

sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;

sCommand.DummyCycles = 0;

sCommand.NbData = 1;



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



res = HAL_OSPI_Receive(&hospi1, &reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



sCommand.DataMode = HAL_OSPI_DATA_NONE;

sCommand.Instruction = VOLATILE_SR_WRITE_ENABLE;



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



sCommand.DataMode = HAL_OSPI_DATA_1_LINE;

sCommand.Instruction = WRITE_STATUS_REG2_CMD;

reg |= 0x02;



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



res = HAL_OSPI_Transmit(&hospi1, &reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



 CS_DISABLE();



return HAL_OK;

}



static uint8_t qspiConfiguration(void)

{

 CS_ENABLE();



OSPI_RegularCmdTypeDef sCommand = {0};

HAL_StatusTypeDef res;

uint8_t reg;



sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;

sCommand.Instruction = READ_STATUS_REG3_CMD;

sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;

sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

sCommand.DataMode = HAL_OSPI_DATA_1_LINE;

sCommand.DummyCycles = 0;

sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;

sCommand.NbData = 1;



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



res = HAL_OSPI_Receive(&hospi1, &reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



sCommand.Instruction = WRITE_STATUS_REG3_CMD;

reg &= 0x9F;



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



res = HAL_OSPI_Transmit(&hospi1, &reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return res;

}



 CS_DISABLE();



return HAL_OK;

}



uint8_t EFD_init(void)

{

if(enableQuadMode() != HAL_OK) {

return HAL_ERROR;

}



if(writeEnable() != HAL_OK) {

return HAL_ERROR;

}



if(qspiConfiguration() != HAL_OK) {

return HAL_ERROR;

}



HAL_Delay(100);



return HAL_OK;

}



uint8_t EFD_eraseChip(void)

{

 CS_ENABLE();



OSPI_RegularCmdTypeDef sCommand = {0};

HAL_StatusTypeDef res;



if(writeEnable() != HAL_OK) {

return HAL_ERROR;

}



sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;

sCommand.Instruction = CHIP_ERASE_CMD;

sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;

sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

sCommand.DataMode = HAL_OSPI_DATA_NONE;

sCommand.DummyCycles = 0;

sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return HAL_ERROR;

}



 CS_DISABLE();



return HAL_OK;

}



uint8_t EFD_writeData(uint8_t* pBuffer, uint32_t address, uint32_t bufferSize)

{

 CS_ENABLE();



OSPI_RegularCmdTypeDef sCommand = {0};

HAL_StatusTypeDef res;

uint32_t endAddr;

uint32_t currentSize;

uint32_t currentAddr = 0;



while(currentAddr <= address) {

currentAddr += MEMORY_PAGE_SIZE;

}

currentSize = currentAddr - address;



if(currentSize > bufferSize) {

currentSize = bufferSize;

}



currentAddr = address;

endAddr = address + bufferSize;



sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;

sCommand.Instruction = QUAD_IN_FAST_PROG_CMD;

sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;

sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;

sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;

sCommand.DataMode = HAL_OSPI_DATA_1_LINE;

sCommand.NbData = bufferSize;

sCommand.Address = address;

sCommand.DummyCycles = 0;



do {

sCommand.Address = currentAddr;

sCommand.NbData = currentSize;



if(currentSize == 0) {

return HAL_OK;

}



if(writeEnable() != HAL_OK) {

return HAL_ERROR;

}



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return HAL_ERROR;

}



res = HAL_OSPI_Transmit(&hospi1, pBuffer, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return HAL_ERROR;

}



currentAddr += currentSize;

pBuffer += currentSize;

currentSize = ((currentAddr + MEMORY_PAGE_SIZE) > endAddr) ?

(endAddr - currentAddr) : MEMORY_PAGE_SIZE;

} while(currentAddr <= endAddr);



 CS_DISABLE();



return HAL_OK;

}



uint8_t EFD_readData(uint8_t* pBuffer, uint32_t address, uint32_t bufferSize)

{

 CS_ENABLE();



OSPI_RegularCmdTypeDef sCommand = {0};

HAL_StatusTypeDef res;



sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;

sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;

sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES;

sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;

sCommand.Address = address;

sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

sCommand.DataMode = HAL_OSPI_DATA_4_LINES;

sCommand.DummyCycles = 0;

sCommand.NbData = bufferSize;

sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;



res = HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return HAL_ERROR;

}



res = HAL_OSPI_Receive(&hospi1, pBuffer, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);

if(res != HAL_OK) {

return HAL_ERROR;

}



 CS_DISABLE();



return HAL_OK;

}

 

11 REPLIES 11

What is this link?

An external loader for your pin configuration which should be usable with STM32 Cube Programmer.

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