2023-10-23 12:13 PM - edited 2023-10-23 12:14 PM
Hi,
I need the project used to generate the external loader: MX25LM51245G_STM32H573I-DK.stldr. My custom board uses a STM32H563VIT6 and the same octo-spi flash from Macronix used in the STM32H573I-DK board. But with different gpios connections. So this project would be of great help to develop the external flash loader for my board.
Ari
2025-01-21 01:26 AM
Hi @ABasi.2,
Thanks again, now i can debug the main code without errors but only setting the dummycycles in CSP_QSPI_EnableMemoryMappedMode to "26" but it's not a datasheet value i'm not sure is everything correct.
2025-01-21 03:04 AM
Hello Berto
i don't know if its a valid value of dummy cycle, in my CSP_QSPI_EnableMemoryMappedMode i have 10
in all the other function i have 0.
2025-01-21 03:20 AM
Setting it to 26 seems like a complete hack.
Suggests you're using the wrong command or mode for one of the transfer widths or address size.
Working blind with detail furnished.
At least 3 ways to read memory, do all report consistently?
2025-01-21 03:22 AM
Yes you're right, i'm checking the datasheet if I find some errors with commands. I let you know,
Thanks again for support.
2025-01-28 06:33 AM
Hi All,
I found the error, it was an instruction command on Write funcion. Now i see that seems writing correctly but i have problem reading. Can I see how you set up your WriteMemory and EnableMemoryMappedMode functions?
Thanks.
2025-01-28 06:39 AM
hello Berto!
i'm glad you found the error.
yes no problem for the functions, i hope this helps
uint8_t CSP_QSPI_WriteMemory(uint8_t* buffer, uint32_t address,uint32_t buffer_size)
{
XSPI_RegularCmdTypeDef sCommand;
uint32_t end_addr, current_size, current_addr;
// Calculation of the size between the write address and the end of the page
current_addr = 0;
while(current_addr <= address)
{
current_addr += MEMORY_PAGE_SIZE;
}
current_size = current_addr - address;
// Check if the size of the data is less than the remaining place in the page
if(current_size > buffer_size)
{
current_size = buffer_size;
}
// Initialize the adress variables
current_addr = address;
end_addr = address + buffer_size;
sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
sCommand.Instruction = QUAD_IN_FAST_PROG_CMD;
sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressMode = HAL_XSPI_ADDRESS_4_LINES;
sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
sCommand.AlternateBytes = 0;
sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
// Perform the write page by page
do
{
sCommand.Address = current_addr;
sCommand.DataLength = current_size;
if(current_size == 0)
{
return HAL_OK;
}
// Enable write operations
if(QSPI_WriteEnable() != HAL_OK)
{
return HAL_ERROR;
}
// Configure the command
if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
{
return HAL_ERROR;
}
// Transmission of the data
if(HAL_XSPI_Transmit(&hospi1, buffer,HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return HAL_ERROR;
}
// Configure automatic polling mode to wait for end of program
if(QSPI_AutoPollingMemReady(HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return HAL_ERROR;
}
// Update the address and size variables for next page programming
current_addr += current_size;
buffer += current_size;
current_size = ((current_addr + MEMORY_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MEMORY_PAGE_SIZE;
}while(current_addr <= end_addr);
return HAL_OK;
}
uint8_t CSP_QSPI_EnableMemoryMappedMode(void)
{
XSPI_RegularCmdTypeDef sCommand;
XSPI_MemoryMappedTypeDef sMemMappedCfg;
// Enable Memory-Mapped mode--------------------------------------------------
sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Address = 0;
sCommand.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
sCommand.AlternateBytes = 0;
sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
sCommand.DataLength = 0;
sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;
sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
{
return HAL_ERROR;
}
if (HAL_XSPI_MemoryMapped(&hospi1,&sMemMappedCfg) != HAL_OK)
{
return HAL_ERROR;
}
return HAL_OK;
}