2024-12-11 01:16 AM
Hi everyone,
I'm currently working on a project where I need to use Port1 IO[7:4] of OCTOSPI1 on the STM32H735IGT6 MCU to interface with a MT25QL512ABB NOR Flash in Quad-SPI mode with dual-quad mode disabled.
I configured the OCTOSPI1 peripheral in CubeMX as follows:
After generating the code and implementing test logic for writing, erasing, and reading from the NOR Flash, I observed the following:
My test code follows the standard configuration steps to enable writes, send commands, and perform operations like erasing and programming. I even tried reinitializing the peripheral in a loop for multiple operations, but the IOs remain inactive.
I'm attaching a screenshot of my CubeMX configuration and some excerpts from my code:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable the CPU Cache */
CPU_CACHE_Enable();
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_OCTOSPI1_Init();
/* USER CODE BEGIN 2 */
//Test_NOR_Flash();
/* Configure the memory in quad mode ------------------------------------- */
/* Configure the memory in octal mode ------------------------------------- */
QSPI_OctalDtrModeCfg(&OSPIHandle);
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_2;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_32_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
/* Infinite loop */
while (1)
{
switch(step)
{
case 0:
CmdCplt = 0;
/* Enable write operations ------------------------------------------- */
OSPI_WriteEnable(&OSPIHandle);
/* Erasing Sequence ----------------------------------------------- */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.Instruction = SECTOR_ERASE_CMD;
sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
sCommand.DataMode = HAL_OSPI_DATA_NONE;
sCommand.Address = address;
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
if (HAL_OSPI_Command_IT(&OSPIHandle, &sCommand) != HAL_OK)
{
Error_Handler();
}
step++;
break;
case 1:
if(CmdCplt != 0)
{
CmdCplt = 0;
StatusMatch = 0;
/* Configure automatic polling mode to wait for end of erase ------- */
OSPI_AutoPollingMemReady(&OSPIHandle);
step++;
}
break;
case 2:
if(StatusMatch != 0)
{
StatusMatch = 0;
TxCplt = 0;
/* Enable write operations ------------------------------------------- */
OSPI_WriteEnable(&OSPIHandle);
/* Writing Sequence ------------------------------------------------ */
sCommand.Instruction = 0x02;//PAGE_PROG_CMD;
sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
sCommand.DataMode = HAL_OSPI_DATA_4_LINES;
sCommand.NbData = BUFFERSIZE;
sCommand.Address = address;
if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
if (HAL_OSPI_Transmit_IT(&OSPIHandle, aTxBuffer) != HAL_OK)
{
Error_Handler();
}
step++;
}
break;
case 3:
if(TxCplt != 0)
{
TxCplt = 0;
StatusMatch = 0;
/* Configure automatic polling mode to wait for end of program ----- */
OSPI_AutoPollingMemReady(&OSPIHandle);
/* Memory-mapped mode configuration ------------------------------- */
sCommand.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG;
sCommand.DataMode = HAL_OSPI_DATA_1_LINE;
sCommand.NbData = 1;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.DummyCycles = 0;
if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG;
sCommand.Instruction = 0x0B;//IO_DTR_READ_CMD;
sCommand.DummyCycles = 8 ;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
if (HAL_OSPI_MemoryMapped(&OSPIHandle, &sMemMappedCfg) != HAL_OK)
{
Error_Handler();
}
/* Reading Sequence ----------------------------------------------- */
mem_addr = (__IO uint8_t *)(OCTOSPI1_BASE + address);
for (index = 0; index < BUFFERSIZE ; index++)
{
if (*mem_addr != aTxBuffer[index])
{
}
mem_addr++;
}
address += OSPI_PAGE_SIZE;
if(address >= OSPI_END_ADDR)
{
address = 0;
}
/* Re-Initialize OctoSPI*/
HAL_OSPI_DeInit(&OSPIHandle);
HAL_OSPI_Init(&OSPIHandle);
step = 0;
}
break;
default :
Error_Handler();
}
}
}
Any guidance or suggestions would be greatly appreciated!
2024-12-11 02:01 AM - edited 2024-12-11 02:02 AM
Hello @feten_kortoba and welcome to the community;
The IO[7:4] can be mapped to Data [3..0]. So, IO[7:4] can be used as possible remap for quad-SPI mode.
Could you check OCTOSPI GPIOs and clocks configuration?
The configured GPIOs must match the memory connection. If the configuration is not correct, the user must manually configure all the GPIOs, one by one, by clicking directly on each pin.
Also make sure that the output speed is set to "very high" for all the GPIOs.
I recommend you to refer to Table8. STM32CubeMX - Configuration of OCTOSPI parameters in AN5050 and check your OCTOSPI configuration.
Try to disable the cache.
Maybe Overall FAQs for QUADSPI/OCTOSPI/HSPI/XSPI can help you.
Thanks and best regards,
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.