How to make QSPI transmission without delay between Command and Data?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-21 2:23 AM
I need to communicate with FPGA by QuadSPI. I use the NUCLEO-H743ZI2 and FreeRTOS with STM32Cub IDE.
So my code to write data to FPGA looks next:
uint32_t qspi_write(const uint8_t* RXbuf, uint8_t* TXbuf, uint16_t* tx_length) {
sCommand.InstructionMode = QSPI_INSTRUCTION_NONE; /* Specifies the Instruction Mode: value of @ref QSPI_InstructionMode */
sCommand.Instruction = 0; /* Specifies the Instruction to be sent: value (8-bit) between 0x00 and 0xFF */
sCommand.AddressMode = QSPI_ADDRESS_4_LINES; /* Specifies the Address Mode: value of @ref QSPI_AddressMode */
sCommand.AddressSize = QSPI_ADDRESS_32_BITS; /* Specifies the Address Size: value of @ref QSPI_AddressSize */
sCommand.Address = *(uint32_t *) RXbuf; /* Specifies the Address to be sent (Size from 1 to 4 bytes according AddressSize): value (32-bits) between 0x0 and 0xFFFFFFFF */
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; /* Specifies the Alternate Bytes Mode: value of @ref QSPI_AlternateBytesMode */
sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; /* Specifies the Alternate Bytes Size: value of @ref QSPI_AlternateBytesSize */
sCommand.AlternateBytes = 0; /* Specifies the Alternate Bytes to be sent (Size from 1 to 4 bytes according AlternateBytesSize): value (32-bits) between 0x0 and 0xFFFFFFFF */
sCommand.DummyCycles = 1; /* Specifies the Number of Dummy Cycles: number between 0 and 31 */
sCommand.DataMode = QSPI_DATA_4_LINES; /* Specifies the Data Mode (used for dummy cycles and data phases): value of @ref QSPI_DataMode */
sCommand.NbData = (uint32_t) *tx_length; /* Specifies the number of bytes to transfer: value between 0 and 0xFFFFFFFF (0 means undefined length until end of memory)*/
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; /* Specifies the double data rate mode for address, alternate byte and data phase: value of @ref QSPI_DdrMode */
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; /* Specifies if the DDR hold is enabled: value of @ref QSPI_DdrHoldHalfCycle */
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Specifies the send instruction only once mode: value of @ref QSPI_SIOOMode */
configPRINTF( ("qspi: Command to Address = 0x%08x\n", sCommand.Address) );
HAL_StatusTypeDef result = HAL_QSPI_Command(&hqspi, &sCommand, QSPI_TIMEOUT_VALUE);
if ( result != HAL_OK ) {
qspi_error_handler(result);
return result;
}
configPRINTF( ("qspi: Transmit NbData = %d\n", (uint16_t) *tx_length) );
// result = HAL_QSPI_Transmit(&hqspi, TXbuf, QSPI_TIMEOUT_VALUE);
result = HAL_QSPI_Transmit_IT(&hqspi, TXbuf);
if ( result != HAL_OK ) {
qspi_error_handler(result);
return result;
}
return HAL_QSPI_ERROR_NONE;
}
As result, I see by Logic Analyser the next picture:
The first burst of clocks corresponds to the transmission if Command, the 2nd - to the Data. The gap between two bursts is about 0.76 mks in the case of using of HAL_QSPI_Transmit_IT and 1.5 mks in case of HAL_QSPI_Transmit which is somehow strange.
But the main question how I have to organize QSPI transmission without delay between Command and Data?
- Labels:
-
STM32CubeIDE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-21 2:46 AM
Possibly a silly question, but how long does the call to configPRINTF() take?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-21 3:04 AM - edited ‎2025-05-21 3:13 AM
@CTapp.1
If I comment the all configPRINTF() in the code the gap between burst do not change - this I tested before writing a post.
I should mention that my previous project on the same board was used MBed OS - and there was not any gap inside QSPI transmissions. So STM32H7 hardware is able to transmit without any gap/delay. So how to program the same in the FreeRTOS?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-21 3:09 AM
i am on the same page as CTapp.1, you should not have those "prints" on a transmission, normally those kind of prints add a delay around 50/100ms.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-21 3:27 AM
@urbito :
Ok, I have to repeat test. Here is results:
Code:
// configPRINTF( ("qspi: Command to Address = 0x%08x\n", sCommand.Address) );
HAL_StatusTypeDef result = HAL_QSPI_Command(&hqspi, &sCommand, QSPI_TIMEOUT_VALUE);
// if ( result != HAL_OK ) {
// qspi_error_handler(result);
// return result;
// }
// configPRINTF( ("qspi: Transmit NbData = %d\n", (uint16_t) *tx_length) );
// result = HAL_QSPI_Transmit(&hqspi, TXbuf, QSPI_TIMEOUT_VALUE);
result = HAL_QSPI_Transmit_IT(&hqspi, TXbuf);
// if ( result != HAL_OK ) {
// qspi_error_handler(result);
// return result;
// }
return HAL_QSPI_ERROR_NONE;
Logic Analyser:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-21 3:35 AM
Inspect HAL_QSPI_Command source and construct a multi-byte variant
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-22 11:34 PM
I tried to combine the HAL_QSPI_Command and HAL_QSPI_Transmit functions in a single function without additional conditional checks or __HAL_LOCK like functions use.
The result is the same - I see the gap between Command and Data sections during QSPI transmission.
I looked the MBed's realization of the qspi.write - they use same HAL functions:
if (HAL_QSPI_Command(&obj->handle, &st_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
status = QSPI_STATUS_ERROR;
} else {
if (HAL_QSPI_Transmit(&obj->handle, (uint8_t *)data, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
status = QSPI_STATUS_ERROR;
}
}
So obviously either I or FreeRTOS configure some QSPI registers in a wrong way. But I did not find in STM's manuals any explanation about delay between Command and Data transmission.
Any idea what should I check now?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-23 12:08 AM
Could it be that FreeRTOS performs a task switch after the command is initiated and the task waits for completion ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-23 12:59 AM - edited ‎2025-05-23 1:00 AM
@Ozone
I don't think so - as I understand it, FreeRTOS switches tasks using Ticks, which is 1 ms. In this case gap between Command and Data is 0.8-1.6 mks - much smaller. But I am just beginner in using FreeRTOS so I do not know many details...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-23 1:56 AM
Many RTOSes switch to other tasks if the currently running one is waiting for a signal/event to occur.
A lot depends on configuration and task setup.
