cancel
Showing results for 
Search instead for 
Did you mean: 

[ STM32F7 QuadSPI ] HAL_QSPI_Command_IT can not Jump to QUADSPI_IRQHandler

HPham.1590
Senior

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();
		}
	}
}

2 REPLIES 2
Bibin Alias
Associate

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 😀

please give me any another sustainable solution:downcast_face_with_sweat:

Bibin Alias
Associate

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);

}