2020-08-18 12:49 AM
Hello, I'm using QuadSPI to read/write to external flash on STM32F746NG.
I used this example from ST and it's working correctly: https://github.com/STMicroelectronics/STM32CubeF7/tree/master/Projects/STM32746G-Discovery/Examples/QSPI/QSPI_ReadWrite_IT
But when I add this function to my project, with RTOS mode, this function make my program stuck.
I tried to run 2 task paralel and both of them is not working, but when I remove task which include QuadSPI, it's still working correctly:
osThreadDef(MQTTThread, MQTTTask, osPriorityNormal, 0, 1024);
MQTTTaskHandHandle = osThreadCreate(osThread(MQTTThread), client);
osThreadDef(UpdateThread, SyncTask, osPriorityNormal, 0, 256);
UpdateTaskHandle = osThreadCreate(osThread(UpdateThread), client);
In debug mode, when I jump over HAL_QSPI_Command_IT function, pointer jump to TIM6_DAC_IRQHandler instead of QUADSPI_IRQHandler although I set QUADSPI_IRQn with highest priority:
HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x00, 0);
HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
Bellow is my code which running on my QuadSPI task. Anyone can tell me what's wrong in my program? Many thanks.
void SyncTask(void *argument)
{
QSPI_CommandTypeDef sCommand;
uint32_t address = 0;
uint16_t index;
__IO uint8_t step = 0;
CPU_CACHE_Enable();
/* Initialize QuadSPI ------------------------------------------------------ */
QSPIHandle.Instance = QUADSPI;
HAL_QSPI_DeInit(&QSPIHandle);
/* ClockPrescaler set to 2, so QSPI clock = 216MHz / (2+1) = 72MHz */
QSPIHandle.Init.ClockPrescaler = 2;
QSPIHandle.Init.FifoThreshold = 4;
QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
QSPIHandle.Init.FlashSize = POSITION_VAL(0x1000000) - 1;
QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0;
QSPIHandle.Init.FlashID = QSPI_FLASH_ID_1;
QSPIHandle.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
{
Error_Handler();
}
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
for(;;)
{
switch(step)
{
case 0:
CmdCplt = 0;
/* Initialize Reception buffer --------------------------------------- */
for (index = 0; index < BUFFERSIZE; index++)
{
aRxBuffer[index] = 0;
}
/* Enable write operations ------------------------------------------- */
QSPI_WriteEnable(&QSPIHandle);
/* Erasing Sequence -------------------------------------------------- */
sCommand.Instruction = SECTOR_ERASE_CMD;
sCommand.AddressMode = QSPI_ADDRESS_1_LINE;
sCommand.Address = address;
sCommand.DataMode = QSPI_DATA_NONE;
sCommand.DummyCycles = 0;
if (HAL_QSPI_Command_IT(&QSPIHandle, &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 ------- */
QSPI_AutoPollingMemReady(&QSPIHandle);
step++;
}
break;
case 2:
if(StatusMatch != 0)
{
StatusMatch = 0;
TxCplt = 0;
/* Enable write operations ----------------------------------------- */
/* Writing Sequence ------------------------------------------------ */
sCommand.Instruction = QUAD_IN_FAST_PROG_CMD;
sCommand.AddressMode = QSPI_ADDRESS_1_LINE;
sCommand.DataMode = QSPI_DATA_4_LINES;
sCommand.NbData = BUFFERSIZE;
if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
if (HAL_QSPI_Transmit_IT(&QSPIHandle, 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 ----- */
QSPI_AutoPollingMemReady(&QSPIHandle);
step++;
}
break;
case 4:
if(StatusMatch != 0)
{
StatusMatch = 0;
RxCplt = 0;
/* Configure Volatile Configuration register (with new dummy cycles) */
QSPI_DummyCyclesCfg(&QSPIHandle);
/* Reading Sequence ------------------------------------------------ */
sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;
if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
if (HAL_QSPI_Receive_IT(&QSPIHandle, aRxBuffer) != HAL_OK)
{
Error_Handler();
}
step++;
}
break;
case 5:
if (RxCplt != 0)
{
RxCplt = 0;
/* Result comparison ----------------------------------------------- */
for (index = 0; index < BUFFERSIZE; index++)
{
if (aRxBuffer[index] != aTxBuffer[index])
{
my_mqtt_publish(argument,"fail");
mqtt_do_connect(argument);
}
}
my_mqtt_publish(argument,"Done");
mqtt_do_connect(argument);
address += QSPI_PAGE_SIZE;
if(address >= QSPI_END_ADDR)
{
address = 0;
}
step = 0;
}
break;
default :
Error_Handler();
}
}
}
2020-11-05 04:23 AM
I have same problem. after execution's of HAL_QSPI_Command_IT(&hqspi,&sCommand) it did not jump to void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
finally i did not check for call back procced for receive or transmit then the program working according to the command send by HAL_QSPI_Command_IT :grinning_face:
please give me any another sustainable solution:downcast_face_with_sweat:
2020-11-11 02:53 AM
Thank god finally solved my problem.....
when exicute HAL_QSPI_Command_IT(&hqspi,&sCommand) in data transition reception instructions the callback is not called because transition and reception part also come after HAL_QSPI_Command_IT(&hqspi,&sCommand) instruction .after successful reception we got void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi) or
void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi) callback.... but not void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi)
{
qspi_reception = END;
HAL_GPIO_TogglePin(USR_LED_GPIO_Port,USR_LED_Pin);
}
void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi)
{
while(1)
{
HAL_Delay(300);
HAL_GPIO_TogglePin(USR_LED_GPIO_Port,USR_LED_Pin);
}
}
void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
{
qspi_transmission = END;
HAL_GPIO_TogglePin(USR_LED_GPIO_Port,USR_LED_Pin);
}
for example
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesSize=QSPI_ALTERNATE_BYTES_8_BITS;
sCommand.Instruction = CMD_Read_Status_Register_1;
sCommand.AddressMode = QSPI_ADDRESS_NONE;
sCommand.Address = 0;
sCommand.DataMode = QSPI_DATA_1_LINE;
sCommand.DummyCycles = 0;
sCommand.NbData=1;
BUSY100: qspi_cmd_transmission = START;
if (HAL_QSPI_Command_IT(&hqspi,&sCommand)!= HAL_OK)
{
Error_Handler();
}
qspi_reception = START;
if(HAL_QSPI_Receive_DMA(&hqspi,&status_register_1)!=HAL_OK)
{
Error_Handler();
}
else
{
while(qspi_reception != END);
}
but in chip erase like instuction it is only a command no data txn or rxn
so it will call
void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
{
qspi_cmd_transmission = END;
}
eg:
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesSize=QSPI_ALTERNATE_BYTES_8_BITS;
sCommand.Instruction = CMD_64KB_Block_Erase;
sCommand.AddressMode = QSPI_ADDRESS_1_LINE;
sCommand.Address = 0X00;
sCommand.DataMode = QSPI_DATA_NONE;
sCommand.DummyCycles = 0;
sCommand.NbData=0;
qspi_cmd_transmission = START;
if (HAL_QSPI_Command_IT(&hqspi,&sCommand)!= HAL_OK)
{
Error_Handler();
}
else
{
while(qspi_cmd_transmission != END);
}