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; }
View more

 

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 */ }
View more

 


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; }
View more

 

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