STM32L4xx_HAL_Driver  1.14.0
stm32l4xx_hal_ospi.c
Go to the documentation of this file.
1 
215 /* Includes ------------------------------------------------------------------*/
216 #include "stm32l4xx_hal.h"
217 
218 #if defined(OCTOSPI) || defined(OCTOSPI1) || defined(OCTOSPI2)
219 
229 #ifdef HAL_OSPI_MODULE_ENABLED
230 
234 /* Private typedef -----------------------------------------------------------*/
235 
236 /* Private define ------------------------------------------------------------*/
237 #define OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000)
238 #define OSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)OCTOSPI_CR_FMODE_0)
239 #define OSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)OCTOSPI_CR_FMODE_1)
240 #define OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)OCTOSPI_CR_FMODE)
242 #define OSPI_CFG_STATE_MASK 0x00000004U
243 #define OSPI_BUSY_STATE_MASK 0x00000008U
244 
245 #define OSPI_NB_INSTANCE 2U
246 #define OSPI_IOM_NB_PORTS 2U
247 #define OSPI_IOM_PORT_MASK 0x1U
248 
249 /* Private macro -------------------------------------------------------------*/
250 #define IS_OSPI_FUNCTIONAL_MODE(MODE) (((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \
251  ((MODE) == OSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \
252  ((MODE) == OSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \
253  ((MODE) == OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED))
254 
255 /* Private variables ---------------------------------------------------------*/
256 
257 /* Private function prototypes -----------------------------------------------*/
258 static void OSPI_DMACplt (DMA_HandleTypeDef *hdma);
259 static void OSPI_DMAHalfCplt (DMA_HandleTypeDef *hdma);
260 static void OSPI_DMAError (DMA_HandleTypeDef *hdma);
261 static void OSPI_DMAAbortCplt (DMA_HandleTypeDef *hdma);
262 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, FlagStatus State, uint32_t Tickstart, uint32_t Timeout);
263 static HAL_StatusTypeDef OSPI_ConfigCmd (OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd);
264 static HAL_StatusTypeDef OSPIM_GetConfig (uint8_t instance_nb, OSPIM_CfgTypeDef *cfg);
269 /* Exported functions --------------------------------------------------------*/
270 
297 HAL_StatusTypeDef HAL_OSPI_Init (OSPI_HandleTypeDef *hospi)
298 {
299  HAL_StatusTypeDef status = HAL_OK;
300  uint32_t tickstart = HAL_GetTick();
301 
302  /* Check the OSPI handle allocation */
303  if (hospi == NULL)
304  {
305  status = HAL_ERROR;
306  /* No error code can be set set as the handler is null */
307  }
308  else
309  {
310  /* Check the parameters of the initialization structure */
311  assert_param(IS_OSPI_FIFO_THRESHOLD (hospi->Init.FifoThreshold));
312  assert_param(IS_OSPI_DUALQUAD_MODE (hospi->Init.DualQuad));
313  assert_param(IS_OSPI_MEMORY_TYPE (hospi->Init.MemoryType));
314  assert_param(IS_OSPI_DEVICE_SIZE (hospi->Init.DeviceSize));
315  assert_param(IS_OSPI_CS_HIGH_TIME (hospi->Init.ChipSelectHighTime));
316  assert_param(IS_OSPI_FREE_RUN_CLK (hospi->Init.FreeRunningClock));
317  assert_param(IS_OSPI_CLOCK_MODE (hospi->Init.ClockMode));
318  assert_param(IS_OSPI_WRAP_SIZE (hospi->Init.WrapSize));
319  assert_param(IS_OSPI_CLK_PRESCALER (hospi->Init.ClockPrescaler));
320  assert_param(IS_OSPI_SAMPLE_SHIFTING(hospi->Init.SampleShifting));
321  assert_param(IS_OSPI_DHQC (hospi->Init.DelayHoldQuarterCycle));
322  assert_param(IS_OSPI_CS_BOUNDARY (hospi->Init.ChipSelectBoundary));
323 
324  /* Initialize error code */
325  hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
326 
327  /* Check if the state is the reset state */
328  if (hospi->State == HAL_OSPI_STATE_RESET)
329  {
330 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
331  /* Reset Callback pointers in HAL_OSPI_STATE_RESET only */
342 
343  if(hospi->MspInitCallback == NULL)
344  {
346  }
347 
348  /* Init the low level hardware */
349  hospi->MspInitCallback(hospi);
350 #else
351  /* Initialization of the low level hardware */
352  HAL_OSPI_MspInit(hospi);
353 #endif
354 
355  /* Configure the default timeout for the OSPI memory access */
356  status = HAL_OSPI_SetTimeout(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
357  }
358 
359  if (status == HAL_OK)
360  {
361  /* Configure memory type, device size, chip select high time, free running clock, clock mode */
362  MODIFY_REG(hospi->Instance->DCR1, (OCTOSPI_DCR1_MTYP | OCTOSPI_DCR1_DEVSIZE | OCTOSPI_DCR1_CSHT | OCTOSPI_DCR1_FRCK | OCTOSPI_DCR1_CKMODE),
363  (hospi->Init.MemoryType | ((hospi->Init.DeviceSize - 1U) << OCTOSPI_DCR1_DEVSIZE_Pos) |
364  ((hospi->Init.ChipSelectHighTime - 1U) << OCTOSPI_DCR1_CSHT_Pos) | hospi->Init.ClockMode));
365 
366  /* Configure wrap size */
367  MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_WRAPSIZE, hospi->Init.WrapSize);
368 
369  /* Configure chip select boundary */
370  hospi->Instance->DCR3 = (hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos);
371 
372 
373  /* Configure FIFO threshold */
374  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos));
375 
376  /* Wait till busy flag is reset */
377  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
378 
379  if (status == HAL_OK)
380  {
381  /* Configure clock prescaler */
382  MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER, ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos));
383 
384  /* Configure Dual Quad mode */
385  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad);
386 
387  /* Configure sample shifting and delay hold quarter cycle */
388  MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC), (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle));
389 
390  /* Enable OctoSPI */
391  __HAL_OSPI_ENABLE(hospi);
392 
393  /* Enable free running clock if needed : must be done after OSPI enable */
394  if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE)
395  {
396  SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
397  }
398 
399  /* Initialize the OSPI state */
400  if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
401  {
402  hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT;
403  }
404  else
405  {
406  hospi->State = HAL_OSPI_STATE_READY;
407  }
408  }
409  }
410  }
411 
412  /* Return function status */
413  return status;
414 }
415 
422 {
423  /* Prevent unused argument(s) compilation warning */
424  UNUSED(hospi);
425 
426  /* NOTE : This function should not be modified, when the callback is needed,
427  the HAL_OSPI_MspInit can be implemented in the user file
428  */
429 }
430 
436 HAL_StatusTypeDef HAL_OSPI_DeInit(OSPI_HandleTypeDef *hospi)
437 {
438  HAL_StatusTypeDef status = HAL_OK;
439 
440  /* Check the OSPI handle allocation */
441  if (hospi == NULL)
442  {
443  status = HAL_ERROR;
444  /* No error code can be set set as the handler is null */
445  }
446  else
447  {
448  /* Disable OctoSPI */
449  __HAL_OSPI_DISABLE(hospi);
450 
451  /* Disable free running clock if needed : must be done after OSPI disable */
452  CLEAR_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK);
453 
454 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
455  if(hospi->MspDeInitCallback == NULL)
456  {
458  }
459 
460  /* DeInit the low level hardware */
461  hospi->MspDeInitCallback(hospi);
462 #else
463  /* De-initialize the low-level hardware */
464  HAL_OSPI_MspDeInit(hospi);
465 #endif
466 
467  /* Reset the driver state */
468  hospi->State = HAL_OSPI_STATE_RESET;
469  }
470 
471  return status;
472 }
473 
480 {
481  /* Prevent unused argument(s) compilation warning */
482  UNUSED(hospi);
483 
484  /* NOTE : This function should not be modified, when the callback is needed,
485  the HAL_OSPI_MspDeInit can be implemented in the user file
486  */
487 }
488 
520 {
521  __IO uint32_t *data_reg = &hospi->Instance->DR;
522  uint32_t flag = hospi->Instance->SR;
523  uint32_t itsource = hospi->Instance->CR;
524  uint32_t currentstate = hospi->State;
525 
526  /* OctoSPI fifo threshold interrupt occurred -------------------------------*/
527  if (((flag & HAL_OSPI_FLAG_FT) != 0U) && ((itsource & HAL_OSPI_IT_FT) != 0U))
528  {
529  if (currentstate == HAL_OSPI_STATE_BUSY_TX)
530  {
531  /* Write a data in the fifo */
532  *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
533  hospi->pBuffPtr++;
534  hospi->XferCount--;
535  }
536  else if (currentstate == HAL_OSPI_STATE_BUSY_RX)
537  {
538  /* Read a data from the fifo */
539  *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
540  hospi->pBuffPtr++;
541  hospi->XferCount--;
542  }
543  else
544  {
545  /* Nothing to do */
546  }
547 
548  if (hospi->XferCount == 0U)
549  {
550  /* All data have been received or transmitted for the transfer */
551  /* Disable fifo threshold interrupt */
552  __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_FT);
553  }
554 
555  /* Fifo threshold callback */
556 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
557  hospi->FifoThresholdCallback(hospi);
558 #else
560 #endif
561  }
562  /* OctoSPI transfer complete interrupt occurred ----------------------------*/
563  else if (((flag & HAL_OSPI_FLAG_TC) != 0U) && ((itsource & HAL_OSPI_IT_TC) != 0U))
564  {
565  if (currentstate == HAL_OSPI_STATE_BUSY_RX)
566  {
567  if ((hospi->XferCount > 0U) && ((flag & OCTOSPI_SR_FLEVEL) != 0U))
568  {
569  /* Read the last data received in the fifo */
570  *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
571  hospi->pBuffPtr++;
572  hospi->XferCount--;
573  }
574  else if(hospi->XferCount == 0U)
575  {
576  /* Clear flag */
577  hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
578 
579  /* Disable the interrupts */
580  __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
581 
582  /* Update state */
583  hospi->State = HAL_OSPI_STATE_READY;
584 
585  /* RX complete callback */
586 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
587  hospi->RxCpltCallback(hospi);
588 #else
590 #endif
591  }
592  else
593  {
594  /* Nothing to do */
595  }
596  }
597  else
598  {
599  /* Clear flag */
600  hospi->Instance->FCR = HAL_OSPI_FLAG_TC;
601 
602  /* Disable the interrupts */
603  __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
604 
605  /* Update state */
606  hospi->State = HAL_OSPI_STATE_READY;
607 
608  if (currentstate == HAL_OSPI_STATE_BUSY_TX)
609  {
610  /* TX complete callback */
611 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
612  hospi->TxCpltCallback(hospi);
613 #else
615 #endif
616  }
617  else if (currentstate == HAL_OSPI_STATE_BUSY_CMD)
618  {
619  /* Command complete callback */
620 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
621  hospi->CmdCpltCallback(hospi);
622 #else
624 #endif
625  }
626  else if (currentstate == HAL_OSPI_STATE_ABORT)
627  {
628  if (hospi->ErrorCode == HAL_OSPI_ERROR_NONE)
629  {
630  /* Abort called by the user */
631  /* Abort complete callback */
632 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
633  hospi->AbortCpltCallback(hospi);
634 #else
636 #endif
637  }
638  else
639  {
640  /* Abort due to an error (eg : DMA error) */
641  /* Error callback */
642 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
643  hospi->ErrorCallback(hospi);
644 #else
645  HAL_OSPI_ErrorCallback(hospi);
646 #endif
647  }
648  }
649  else
650  {
651  /* Nothing to do */
652  }
653  }
654  }
655  /* OctoSPI status match interrupt occurred ---------------------------------*/
656  else if (((flag & HAL_OSPI_FLAG_SM) != 0U) && ((itsource & HAL_OSPI_IT_SM) != 0U))
657  {
658  /* Clear flag */
659  hospi->Instance->FCR = HAL_OSPI_FLAG_SM;
660 
661  /* Check if automatic poll mode stop is activated */
662  if ((hospi->Instance->CR & OCTOSPI_CR_APMS) != 0U)
663  {
664  /* Disable the interrupts */
665  __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
666 
667  /* Update state */
668  hospi->State = HAL_OSPI_STATE_READY;
669  }
670 
671  /* Status match callback */
672 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
673  hospi->StatusMatchCallback(hospi);
674 #else
676 #endif
677  }
678  /* OctoSPI transfer error interrupt occurred -------------------------------*/
679  else if (((flag & HAL_OSPI_FLAG_TE) != 0U) && ((itsource & HAL_OSPI_IT_TE) != 0U))
680  {
681  /* Clear flag */
682  hospi->Instance->FCR = HAL_OSPI_FLAG_TE;
683 
684  /* Disable all interrupts */
685  __HAL_OSPI_DISABLE_IT(hospi, (HAL_OSPI_IT_TO | HAL_OSPI_IT_SM | HAL_OSPI_IT_FT | HAL_OSPI_IT_TC | HAL_OSPI_IT_TE));
686 
687  /* Set error code */
688  hospi->ErrorCode = HAL_OSPI_ERROR_TRANSFER;
689 
690  /* Check if the DMA is enabled */
691  if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
692  {
693  /* Disable the DMA transfer on the OctoSPI side */
694  CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
695 
696  /* Disable the DMA transfer on the DMA side */
697  hospi->hdma->XferAbortCallback = OSPI_DMAAbortCplt;
698  if (HAL_DMA_Abort_IT(hospi->hdma) != HAL_OK)
699  {
700  /* Update state */
701  hospi->State = HAL_OSPI_STATE_READY;
702 
703  /* Error callback */
704 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
705  hospi->ErrorCallback(hospi);
706 #else
707  HAL_OSPI_ErrorCallback(hospi);
708 #endif
709  }
710  }
711  else
712  {
713  /* Update state */
714  hospi->State = HAL_OSPI_STATE_READY;
715 
716  /* Error callback */
717 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
718  hospi->ErrorCallback(hospi);
719 #else
720  HAL_OSPI_ErrorCallback(hospi);
721 #endif
722  }
723  }
724  /* OctoSPI timeout interrupt occurred --------------------------------------*/
725  else if (((flag & HAL_OSPI_FLAG_TO) != 0U) && ((itsource & HAL_OSPI_IT_TO) != 0U))
726  {
727  /* Clear flag */
728  hospi->Instance->FCR = HAL_OSPI_FLAG_TO;
729 
730  /* Timeout callback */
731 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
732  hospi->TimeOutCallback(hospi);
733 #else
735 #endif
736  }
737  else
738  {
739  /* Nothing to do */
740  }
741 }
742 
750 HAL_StatusTypeDef HAL_OSPI_Command(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd, uint32_t Timeout)
751 {
752  HAL_StatusTypeDef status;
753  uint32_t state;
754  uint32_t tickstart = HAL_GetTick();
755 
756  /* Check the parameters of the command structure */
757  assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
758 
759  if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
760  {
761  assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
762  }
763 
764  assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
765  if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
766  {
767  assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd->InstructionSize));
768  assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
769  }
770 
771  assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
772  if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
773  {
774  assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
775  assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
776  }
777 
778  assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
779  if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
780  {
781  assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd->AlternateBytesSize));
782  assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
783  }
784 
785  assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
786  if (cmd->DataMode != HAL_OSPI_DATA_NONE)
787  {
788  if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
789  {
790  assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData));
791  }
792  assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
793  assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles));
794  }
795 
796  assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
797  assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
798 
799  /* Check the state of the driver */
800  state = hospi->State;
801  if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) ||
802  ((state == HAL_OSPI_STATE_READ_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)) ||
803  ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)))
804  {
805  /* Wait till busy flag is reset */
806  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
807 
808  if (status == HAL_OK)
809  {
810  /* Initialize error code */
811  hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
812 
813  /* Configure the registers */
814  status = OSPI_ConfigCmd(hospi, cmd);
815 
816  if (status == HAL_OK)
817  {
818  if (cmd->DataMode == HAL_OSPI_DATA_NONE)
819  {
820  /* When there is no data phase, the transfer start as soon as the configuration is done
821  so wait until TC flag is set to go back in idle state */
822  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
823 
824  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
825  }
826  else
827  {
828  /* Update the state */
829  if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
830  {
831  hospi->State = HAL_OSPI_STATE_CMD_CFG;
832  }
833  else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG)
834  {
835  if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG)
836  {
837  hospi->State = HAL_OSPI_STATE_CMD_CFG;
838  }
839  else
840  {
841  hospi->State = HAL_OSPI_STATE_READ_CMD_CFG;
842  }
843  }
844  else
845  {
846  if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG)
847  {
848  hospi->State = HAL_OSPI_STATE_CMD_CFG;
849  }
850  else
851  {
852  hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG;
853  }
854  }
855  }
856  }
857  }
858  }
859  else
860  {
861  status = HAL_ERROR;
862  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
863  }
864 
865  /* Return function status */
866  return status;
867 }
868 
877 {
878  HAL_StatusTypeDef status;
879  uint32_t tickstart = HAL_GetTick();
880 
881  /* Check the parameters of the command structure */
882  assert_param(IS_OSPI_OPERATION_TYPE(cmd->OperationType));
883 
884  if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
885  {
886  assert_param(IS_OSPI_FLASH_ID(cmd->FlashId));
887  }
888 
889  assert_param(IS_OSPI_INSTRUCTION_MODE(cmd->InstructionMode));
890  if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
891  {
892  assert_param(IS_OSPI_INSTRUCTION_SIZE (cmd->InstructionSize));
893  assert_param(IS_OSPI_INSTRUCTION_DTR_MODE(cmd->InstructionDtrMode));
894  }
895 
896  assert_param(IS_OSPI_ADDRESS_MODE(cmd->AddressMode));
897  if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
898  {
899  assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
900  assert_param(IS_OSPI_ADDRESS_DTR_MODE(cmd->AddressDtrMode));
901  }
902 
903  assert_param(IS_OSPI_ALT_BYTES_MODE(cmd->AlternateBytesMode));
904  if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
905  {
906  assert_param(IS_OSPI_ALT_BYTES_SIZE (cmd->AlternateBytesSize));
907  assert_param(IS_OSPI_ALT_BYTES_DTR_MODE(cmd->AlternateBytesDtrMode));
908  }
909 
910  assert_param(IS_OSPI_DATA_MODE(cmd->DataMode));
911  if (cmd->DataMode != HAL_OSPI_DATA_NONE)
912  {
913  assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData));
914  assert_param(IS_OSPI_DATA_DTR_MODE(cmd->DataDtrMode));
915  assert_param(IS_OSPI_DUMMY_CYCLES (cmd->DummyCycles));
916  }
917 
918  assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
919  assert_param(IS_OSPI_SIOO_MODE(cmd->SIOOMode));
920 
921  /* Check the state of the driver */
922  if ((hospi->State == HAL_OSPI_STATE_READY) && (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) &&
923  (cmd->DataMode == HAL_OSPI_DATA_NONE) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS))
924  {
925  /* Wait till busy flag is reset */
926  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
927 
928  if (status == HAL_OK)
929  {
930  /* Initialize error code */
931  hospi->ErrorCode = HAL_OSPI_ERROR_NONE;
932 
933  /* Clear flags related to interrupt */
934  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
935 
936  /* Configure the registers */
937  status = OSPI_ConfigCmd(hospi, cmd);
938 
939  if (status == HAL_OK)
940  {
941  /* Update the state */
942  hospi->State = HAL_OSPI_STATE_BUSY_CMD;
943 
944  /* Enable the transfer complete and transfer error interrupts */
945  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_TE);
946  }
947  }
948  }
949  else
950  {
951  status = HAL_ERROR;
952  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
953  }
954 
955  /* Return function status */
956  return status;
957 }
958 
966 HAL_StatusTypeDef HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCfgTypeDef *cfg, uint32_t Timeout)
967 {
968  HAL_StatusTypeDef status;
969  uint32_t state;
970  uint32_t tickstart = HAL_GetTick();
971 
972  /* Check the parameters of the hyperbus configuration structure */
973  assert_param(IS_OSPI_RW_RECOVERY_TIME (cfg->RWRecoveryTime));
974  assert_param(IS_OSPI_ACCESS_TIME (cfg->AccessTime));
975  assert_param(IS_OSPI_WRITE_ZERO_LATENCY(cfg->WriteZeroLatency));
976  assert_param(IS_OSPI_LATENCY_MODE (cfg->LatencyMode));
977 
978  /* Check the state of the driver */
979  state = hospi->State;
980  if ((state == HAL_OSPI_STATE_HYPERBUS_INIT) || (state == HAL_OSPI_STATE_READY))
981  {
982  /* Wait till busy flag is reset */
983  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
984 
985  if (status == HAL_OK)
986  {
987  /* Configure Hyperbus configuration Latency register */
988  WRITE_REG(hospi->Instance->HLCR, ((cfg->RWRecoveryTime << OCTOSPI_HLCR_TRWR_Pos) |
989  (cfg->AccessTime << OCTOSPI_HLCR_TACC_Pos) |
990  cfg->WriteZeroLatency | cfg->LatencyMode));
991 
992  /* Update the state */
993  hospi->State = HAL_OSPI_STATE_READY;
994  }
995  }
996  else
997  {
998  status = HAL_ERROR;
999  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1000  }
1001 
1002  /* Return function status */
1003  return status;
1004 }
1005 
1013 HAL_StatusTypeDef HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCmdTypeDef *cmd, uint32_t Timeout)
1014 {
1015  HAL_StatusTypeDef status;
1016  uint32_t tickstart = HAL_GetTick();
1017 
1018  /* Check the parameters of the hyperbus command structure */
1019  assert_param(IS_OSPI_ADDRESS_SPACE(cmd->AddressSpace));
1020  assert_param(IS_OSPI_ADDRESS_SIZE (cmd->AddressSize));
1021  assert_param(IS_OSPI_NUMBER_DATA (cmd->NbData));
1022  assert_param(IS_OSPI_DQS_MODE (cmd->DQSMode));
1023 
1024  /* Check the state of the driver */
1025  if ((hospi->State == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS))
1026  {
1027  /* Wait till busy flag is reset */
1028  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1029 
1030  if (status == HAL_OK)
1031  {
1032  /* Re-initialize the value of the functional mode */
1033  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
1034 
1035  /* Configure the address space in the DCR1 register */
1036  MODIFY_REG(hospi->Instance->DCR1, OCTOSPI_DCR1_MTYP_0, cmd->AddressSpace);
1037 
1038  /* Configure the CCR and WCCR registers with the address size and the following configuration :
1039  - DQS signal enabled (used as RWDS)
1040  - DTR mode enabled on address and data
1041  - address and data on 8 lines */
1042  WRITE_REG(hospi->Instance->CCR, (cmd->DQSMode | OCTOSPI_CCR_DDTR | OCTOSPI_CCR_DMODE_2 |
1043  cmd->AddressSize | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADMODE_2));
1044  WRITE_REG(hospi->Instance->WCCR, (cmd->DQSMode | OCTOSPI_WCCR_DDTR | OCTOSPI_WCCR_DMODE_2 |
1045  cmd->AddressSize | OCTOSPI_WCCR_ADDTR | OCTOSPI_WCCR_ADMODE_2));
1046 
1047  /* Configure the DLR register with the number of data */
1048  WRITE_REG(hospi->Instance->DLR, (cmd->NbData - 1U));
1049 
1050  /* Configure the AR register with the address value */
1051  WRITE_REG(hospi->Instance->AR, cmd->Address);
1052 
1053  /* Update the state */
1054  hospi->State = HAL_OSPI_STATE_CMD_CFG;
1055  }
1056  }
1057  else
1058  {
1059  status = HAL_ERROR;
1060  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1061  }
1062 
1063  /* Return function status */
1064  return status;
1065 }
1066 
1075 HAL_StatusTypeDef HAL_OSPI_Transmit(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
1076 {
1077  HAL_StatusTypeDef status;
1078  uint32_t tickstart = HAL_GetTick();
1079  __IO uint32_t *data_reg = &hospi->Instance->DR;
1080 
1081  /* Check the data pointer allocation */
1082  if (pData == NULL)
1083  {
1084  status = HAL_ERROR;
1085  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1086  }
1087  else
1088  {
1089  /* Check the state */
1090  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1091  {
1092  /* Configure counters and size */
1093  hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1094  hospi->XferSize = hospi->XferCount;
1095  hospi->pBuffPtr = pData;
1096 
1097  /* Configure CR register with functional mode as indirect write */
1098  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1099 
1100  do
1101  {
1102  /* Wait till fifo threshold flag is set to send data */
1103  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_FT, SET, tickstart, Timeout);
1104 
1105  if (status != HAL_OK)
1106  {
1107  break;
1108  }
1109 
1110  *((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;
1111  hospi->pBuffPtr++;
1112  hospi->XferCount--;
1113  } while (hospi->XferCount > 0U);
1114 
1115  if (status == HAL_OK)
1116  {
1117  /* Wait till transfer complete flag is set to go back in idle state */
1118  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1119 
1120  if (status == HAL_OK)
1121  {
1122  /* Clear transfer complete flag */
1123  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1124 
1125  /* Update state */
1126  hospi->State = HAL_OSPI_STATE_READY;
1127  }
1128  }
1129  }
1130  else
1131  {
1132  status = HAL_ERROR;
1133  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1134  }
1135  }
1136 
1137  /* Return function status */
1138  return status;
1139 }
1140 
1149 HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
1150 {
1151  HAL_StatusTypeDef status;
1152  uint32_t tickstart = HAL_GetTick();
1153  __IO uint32_t *data_reg = &hospi->Instance->DR;
1154  uint32_t addr_reg = hospi->Instance->AR;
1155  uint32_t ir_reg = hospi->Instance->IR;
1156 
1157  /* Check the data pointer allocation */
1158  if (pData == NULL)
1159  {
1160  status = HAL_ERROR;
1161  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1162  }
1163  else
1164  {
1165  /* Check the state */
1166  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1167  {
1168  /* Configure counters and size */
1169  hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1170  hospi->XferSize = hospi->XferCount;
1171  hospi->pBuffPtr = pData;
1172 
1173  /* Configure CR register with functional mode as indirect read */
1174  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1175 
1176  /* Trig the transfer by re-writing address or instruction register */
1177  if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1178  {
1179  WRITE_REG(hospi->Instance->AR, addr_reg);
1180  }
1181  else
1182  {
1183  if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1184  {
1185  WRITE_REG(hospi->Instance->AR, addr_reg);
1186  }
1187  else
1188  {
1189  WRITE_REG(hospi->Instance->IR, ir_reg);
1190  }
1191  }
1192 
1193  do
1194  {
1195  /* Wait till fifo threshold or transfer complete flags are set to read received data */
1196  status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout);
1197 
1198  if (status != HAL_OK)
1199  {
1200  break;
1201  }
1202 
1203  *hospi->pBuffPtr = *((__IO uint8_t *)data_reg);
1204  hospi->pBuffPtr++;
1205  hospi->XferCount--;
1206  } while(hospi->XferCount > 0U);
1207 
1208  if (status == HAL_OK)
1209  {
1210  /* Wait till transfer complete flag is set to go back in idle state */
1211  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout);
1212 
1213  if (status == HAL_OK)
1214  {
1215  /* Clear transfer complete flag */
1216  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
1217 
1218  /* Update state */
1219  hospi->State = HAL_OSPI_STATE_READY;
1220  }
1221  }
1222  }
1223  else
1224  {
1225  status = HAL_ERROR;
1226  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1227  }
1228  }
1229 
1230  /* Return function status */
1231  return status;
1232 }
1233 
1241 HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1242 {
1243  HAL_StatusTypeDef status = HAL_OK;
1244 
1245  /* Check the data pointer allocation */
1246  if (pData == NULL)
1247  {
1248  status = HAL_ERROR;
1249  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1250  }
1251  else
1252  {
1253  /* Check the state */
1254  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1255  {
1256  /* Configure counters and size */
1257  hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1258  hospi->XferSize = hospi->XferCount;
1259  hospi->pBuffPtr = pData;
1260 
1261  /* Configure CR register with functional mode as indirect write */
1262  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1263 
1264  /* Clear flags related to interrupt */
1265  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1266 
1267  /* Update the state */
1268  hospi->State = HAL_OSPI_STATE_BUSY_TX;
1269 
1270  /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1271  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1272  }
1273  else
1274  {
1275  status = HAL_ERROR;
1276  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1277  }
1278  }
1279 
1280  /* Return function status */
1281  return status;
1282 }
1283 
1291 HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1292 {
1293  HAL_StatusTypeDef status = HAL_OK;
1294  uint32_t addr_reg = hospi->Instance->AR;
1295  uint32_t ir_reg = hospi->Instance->IR;
1296 
1297  /* Check the data pointer allocation */
1298  if (pData == NULL)
1299  {
1300  status = HAL_ERROR;
1301  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1302  }
1303  else
1304  {
1305  /* Check the state */
1306  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1307  {
1308  /* Configure counters and size */
1309  hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U;
1310  hospi->XferSize = hospi->XferCount;
1311  hospi->pBuffPtr = pData;
1312 
1313  /* Configure CR register with functional mode as indirect read */
1314  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1315 
1316  /* Clear flags related to interrupt */
1317  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1318 
1319  /* Update the state */
1320  hospi->State = HAL_OSPI_STATE_BUSY_RX;
1321 
1322  /* Enable the transfer complete, fifo threshold and transfer error interrupts */
1323  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
1324 
1325  /* Trig the transfer by re-writing address or instruction register */
1326  if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1327  {
1328  WRITE_REG(hospi->Instance->AR, addr_reg);
1329  }
1330  else
1331  {
1332  if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1333  {
1334  WRITE_REG(hospi->Instance->AR, addr_reg);
1335  }
1336  else
1337  {
1338  WRITE_REG(hospi->Instance->IR, ir_reg);
1339  }
1340  }
1341  }
1342  else
1343  {
1344  status = HAL_ERROR;
1345  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1346  }
1347  }
1348 
1349  /* Return function status */
1350  return status;
1351 }
1352 
1364 HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1365 {
1366  HAL_StatusTypeDef status = HAL_OK;
1367  uint32_t data_size = hospi->Instance->DLR + 1U;
1368 
1369  /* Check the data pointer allocation */
1370  if (pData == NULL)
1371  {
1372  status = HAL_ERROR;
1373  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1374  }
1375  else
1376  {
1377  /* Check the state */
1378  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1379  {
1380  /* Configure counters and size */
1381  if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1382  {
1383  hospi->XferCount = data_size;
1384  }
1385  else if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1386  {
1387  if (((data_size % 2U) != 0U) || ((hospi->Init.FifoThreshold % 2U) != 0U))
1388  {
1389  /* The number of data or the fifo threshold is not aligned on halfword
1390  => no transfer possible with DMA peripheral access configured as halfword */
1391  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1392  status = HAL_ERROR;
1393  }
1394  else
1395  {
1396  hospi->XferCount = (data_size >> 1);
1397  }
1398  }
1399  else if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1400  {
1401  if (((data_size % 4U) != 0U) || ((hospi->Init.FifoThreshold % 4U) != 0U))
1402  {
1403  /* The number of data or the fifo threshold is not aligned on word
1404  => no transfer possible with DMA peripheral access configured as word */
1405  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1406  status = HAL_ERROR;
1407  }
1408  else
1409  {
1410  hospi->XferCount = (data_size >> 2);
1411  }
1412  }
1413  else
1414  {
1415  /* Nothing to do */
1416  }
1417 
1418  if (status == HAL_OK)
1419  {
1420  hospi->XferSize = hospi->XferCount;
1421  hospi->pBuffPtr = pData;
1422 
1423  /* Configure CR register with functional mode as indirect write */
1424  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_WRITE);
1425 
1426  /* Clear flags related to interrupt */
1427  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1428 
1429  /* Update the state */
1430  hospi->State = HAL_OSPI_STATE_BUSY_TX;
1431 
1432  /* Set the DMA transfer complete callback */
1433  hospi->hdma->XferCpltCallback = OSPI_DMACplt;
1434 
1435  /* Set the DMA Half transfer complete callback */
1436  hospi->hdma->XferHalfCpltCallback = OSPI_DMAHalfCplt;
1437 
1438  /* Set the DMA error callback */
1439  hospi->hdma->XferErrorCallback = OSPI_DMAError;
1440 
1441  /* Clear the DMA abort callback */
1442  hospi->hdma->XferAbortCallback = NULL;
1443 
1444  /* Configure the direction of the DMA */
1445  hospi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
1446  MODIFY_REG(hospi->hdma->Instance->CCR, DMA_CCR_DIR, hospi->hdma->Init.Direction);
1447 
1448  /* Enable the transmit DMA Channel */
1449  if (HAL_DMA_Start_IT(hospi->hdma, (uint32_t)pData, (uint32_t)&hospi->Instance->DR, hospi->XferSize) == HAL_OK)
1450  {
1451  /* Enable the transfer error interrupt */
1452  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1453 
1454  /* Enable the DMA transfer by setting the DMAEN bit */
1455  SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
1456  }
1457  else
1458  {
1459  status = HAL_ERROR;
1460  hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1461  hospi->State = HAL_OSPI_STATE_READY;
1462  }
1463  }
1464  }
1465  else
1466  {
1467  status = HAL_ERROR;
1468  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1469  }
1470  }
1471 
1472  /* Return function status */
1473  return status;
1474 }
1475 
1487 HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
1488 {
1489  HAL_StatusTypeDef status = HAL_OK;
1490  uint32_t data_size = hospi->Instance->DLR + 1U;
1491  uint32_t addr_reg = hospi->Instance->AR;
1492  uint32_t ir_reg = hospi->Instance->IR;
1493 
1494  /* Check the data pointer allocation */
1495  if (pData == NULL)
1496  {
1497  status = HAL_ERROR;
1498  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1499  }
1500  else
1501  {
1502  /* Check the state */
1503  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1504  {
1505  /* Configure counters and size */
1506  if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1507  {
1508  hospi->XferCount = data_size;
1509  }
1510  else if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_HALFWORD)
1511  {
1512  if (((data_size % 2U) != 0U) || ((hospi->Init.FifoThreshold % 2U) != 0U))
1513  {
1514  /* The number of data or the fifo threshold is not aligned on halfword
1515  => no transfer possible with DMA peripheral access configured as halfword */
1516  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1517  status = HAL_ERROR;
1518  }
1519  else
1520  {
1521  hospi->XferCount = (data_size >> 1);
1522  }
1523  }
1524  else if (hospi->hdma->Init.PeriphDataAlignment == DMA_PDATAALIGN_WORD)
1525  {
1526  if (((data_size % 4U) != 0U) || ((hospi->Init.FifoThreshold % 4U) != 0U))
1527  {
1528  /* The number of data or the fifo threshold is not aligned on word
1529  => no transfer possible with DMA peripheral access configured as word */
1530  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
1531  status = HAL_ERROR;
1532  }
1533  else
1534  {
1535  hospi->XferCount = (data_size >> 2);
1536  }
1537  }
1538  else
1539  {
1540  /* Nothing to do */
1541  }
1542 
1543  if (status == HAL_OK)
1544  {
1545  hospi->XferSize = hospi->XferCount;
1546  hospi->pBuffPtr = pData;
1547 
1548  /* Configure CR register with functional mode as indirect read */
1549  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ);
1550 
1551  /* Clear flags related to interrupt */
1552  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_TC);
1553 
1554  /* Update the state */
1555  hospi->State = HAL_OSPI_STATE_BUSY_RX;
1556 
1557  /* Set the DMA transfer complete callback */
1558  hospi->hdma->XferCpltCallback = OSPI_DMACplt;
1559 
1560  /* Set the DMA Half transfer complete callback */
1561  hospi->hdma->XferHalfCpltCallback = OSPI_DMAHalfCplt;
1562 
1563  /* Set the DMA error callback */
1564  hospi->hdma->XferErrorCallback = OSPI_DMAError;
1565 
1566  /* Clear the DMA abort callback */
1567  hospi->hdma->XferAbortCallback = NULL;
1568 
1569  /* Configure the direction of the DMA */
1570  hospi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
1571  MODIFY_REG(hospi->hdma->Instance->CCR, DMA_CCR_DIR, hospi->hdma->Init.Direction);
1572 
1573  /* Enable the transmit DMA Channel */
1574  if (HAL_DMA_Start_IT(hospi->hdma, (uint32_t)&hospi->Instance->DR, (uint32_t)pData, hospi->XferSize) == HAL_OK)
1575  {
1576  /* Enable the transfer error interrupt */
1577  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TE);
1578 
1579  /* Trig the transfer by re-writing address or instruction register */
1580  if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1581  {
1582  WRITE_REG(hospi->Instance->AR, addr_reg);
1583  }
1584  else
1585  {
1586  if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1587  {
1588  WRITE_REG(hospi->Instance->AR, addr_reg);
1589  }
1590  else
1591  {
1592  WRITE_REG(hospi->Instance->IR, ir_reg);
1593  }
1594  }
1595 
1596  /* Enable the DMA transfer by setting the DMAEN bit */
1597  SET_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
1598  }
1599  else
1600  {
1601  status = HAL_ERROR;
1602  hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
1603  hospi->State = HAL_OSPI_STATE_READY;
1604  }
1605  }
1606  }
1607  else
1608  {
1609  status = HAL_ERROR;
1610  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1611  }
1612  }
1613 
1614  /* Return function status */
1615  return status;
1616 }
1617 
1627 HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
1628 {
1629  HAL_StatusTypeDef status;
1630  uint32_t tickstart = HAL_GetTick();
1631  uint32_t addr_reg = hospi->Instance->AR;
1632  uint32_t ir_reg = hospi->Instance->IR;
1633 #ifdef USE_FULL_ASSERT
1634  uint32_t dlr_reg = hospi->Instance->DLR;
1635 #endif
1636 
1637  /* Check the parameters of the autopolling configuration structure */
1638  assert_param(IS_OSPI_MATCH_MODE (cfg->MatchMode));
1639  assert_param(IS_OSPI_AUTOMATIC_STOP (cfg->AutomaticStop));
1640  assert_param(IS_OSPI_INTERVAL (cfg->Interval));
1641  assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U));
1642 
1643  /* Check the state */
1644  if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE))
1645  {
1646  /* Wait till busy flag is reset */
1647  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout);
1648 
1649  if (status == HAL_OK)
1650  {
1651  /* Configure registers */
1652  WRITE_REG (hospi->Instance->PSMAR, cfg->Match);
1653  WRITE_REG (hospi->Instance->PSMKR, cfg->Mask);
1654  WRITE_REG (hospi->Instance->PIR, cfg->Interval);
1655  MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1656  (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1657 
1658  /* Trig the transfer by re-writing address or instruction register */
1659  if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1660  {
1661  WRITE_REG(hospi->Instance->AR, addr_reg);
1662  }
1663  else
1664  {
1665  if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1666  {
1667  WRITE_REG(hospi->Instance->AR, addr_reg);
1668  }
1669  else
1670  {
1671  WRITE_REG(hospi->Instance->IR, ir_reg);
1672  }
1673  }
1674 
1675  /* Wait till status match flag is set to go back in idle state */
1676  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout);
1677 
1678  if (status == HAL_OK)
1679  {
1680  /* Clear status match flag */
1681  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM);
1682 
1683  /* Update state */
1684  hospi->State = HAL_OSPI_STATE_READY;
1685  }
1686  }
1687  }
1688  else
1689  {
1690  status = HAL_ERROR;
1691  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1692  }
1693 
1694  /* Return function status */
1695  return status;
1696 }
1697 
1707 {
1708  HAL_StatusTypeDef status;
1709  uint32_t tickstart = HAL_GetTick();
1710  uint32_t addr_reg = hospi->Instance->AR;
1711  uint32_t ir_reg = hospi->Instance->IR;
1712 #ifdef USE_FULL_ASSERT
1713  uint32_t dlr_reg = hospi->Instance->DLR;
1714 #endif
1715 
1716  /* Check the parameters of the autopolling configuration structure */
1717  assert_param(IS_OSPI_MATCH_MODE (cfg->MatchMode));
1718  assert_param(IS_OSPI_AUTOMATIC_STOP (cfg->AutomaticStop));
1719  assert_param(IS_OSPI_INTERVAL (cfg->Interval));
1720  assert_param(IS_OSPI_STATUS_BYTES_SIZE(dlr_reg+1U));
1721 
1722  /* Check the state */
1723  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1724  {
1725  /* Wait till busy flag is reset */
1726  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1727 
1728  if (status == HAL_OK)
1729  {
1730  /* Configure registers */
1731  WRITE_REG (hospi->Instance->PSMAR, cfg->Match);
1732  WRITE_REG (hospi->Instance->PSMKR, cfg->Mask);
1733  WRITE_REG (hospi->Instance->PIR, cfg->Interval);
1734  MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE),
1735  (cfg->MatchMode | cfg->AutomaticStop | OSPI_FUNCTIONAL_MODE_AUTO_POLLING));
1736 
1737  /* Clear flags related to interrupt */
1738  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM);
1739 
1740  /* Update state */
1741  hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING;
1742 
1743  /* Enable the status match and transfer error interrupts */
1744  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE);
1745 
1746  /* Trig the transfer by re-writing address or instruction register */
1747  if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS)
1748  {
1749  WRITE_REG(hospi->Instance->AR, addr_reg);
1750  }
1751  else
1752  {
1753  if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE)
1754  {
1755  WRITE_REG(hospi->Instance->AR, addr_reg);
1756  }
1757  else
1758  {
1759  WRITE_REG(hospi->Instance->IR, ir_reg);
1760  }
1761  }
1762  }
1763  }
1764  else
1765  {
1766  status = HAL_ERROR;
1767  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1768  }
1769 
1770  /* Return function status */
1771  return status;
1772 }
1773 
1782 {
1783  HAL_StatusTypeDef status;
1784  uint32_t tickstart = HAL_GetTick();
1785 
1786  /* Check the parameters of the memory-mapped configuration structure */
1787  assert_param(IS_OSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation));
1788 
1789  /* Check the state */
1790  if (hospi->State == HAL_OSPI_STATE_CMD_CFG)
1791  {
1792  /* Wait till busy flag is reset */
1793  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
1794 
1795  if (status == HAL_OK)
1796  {
1797  /* Update state */
1798  hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED;
1799 
1800  if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE)
1801  {
1802  assert_param(IS_OSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod));
1803 
1804  /* Configure register */
1805  WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod);
1806 
1807  /* Clear flags related to interrupt */
1808  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO);
1809 
1810  /* Enable the timeout interrupt */
1811  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO);
1812  }
1813 
1814  /* Configure CR register with functional mode as memory-mapped */
1815  MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE),
1816  (cfg->TimeOutActivation | OSPI_FUNCTIONAL_MODE_MEMORY_MAPPED));
1817  }
1818  }
1819  else
1820  {
1821  status = HAL_ERROR;
1822  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
1823  }
1824 
1825  /* Return function status */
1826  return status;
1827 }
1828 
1835 {
1836  /* Prevent unused argument(s) compilation warning */
1837  UNUSED(hospi);
1838 
1839  /* NOTE : This function should not be modified, when the callback is needed,
1840  the HAL_OSPI_ErrorCallback could be implemented in the user file
1841  */
1842 }
1843 
1850 {
1851  /* Prevent unused argument(s) compilation warning */
1852  UNUSED(hospi);
1853 
1854  /* NOTE: This function should not be modified, when the callback is needed,
1855  the HAL_OSPI_AbortCpltCallback could be implemented in the user file
1856  */
1857 }
1858 
1865 {
1866  /* Prevent unused argument(s) compilation warning */
1867  UNUSED(hospi);
1868 
1869  /* NOTE : This function should not be modified, when the callback is needed,
1870  the HAL_OSPI_FIFOThresholdCallback could be implemented in the user file
1871  */
1872 }
1873 
1880 {
1881  /* Prevent unused argument(s) compilation warning */
1882  UNUSED(hospi);
1883 
1884  /* NOTE: This function should not be modified, when the callback is needed,
1885  the HAL_OSPI_CmdCpltCallback could be implemented in the user file
1886  */
1887 }
1888 
1895 {
1896  /* Prevent unused argument(s) compilation warning */
1897  UNUSED(hospi);
1898 
1899  /* NOTE: This function should not be modified, when the callback is needed,
1900  the HAL_OSPI_RxCpltCallback could be implemented in the user file
1901  */
1902 }
1903 
1910 {
1911  /* Prevent unused argument(s) compilation warning */
1912  UNUSED(hospi);
1913 
1914  /* NOTE: This function should not be modified, when the callback is needed,
1915  the HAL_OSPI_TxCpltCallback could be implemented in the user file
1916  */
1917 }
1918 
1925 {
1926  /* Prevent unused argument(s) compilation warning */
1927  UNUSED(hospi);
1928 
1929  /* NOTE: This function should not be modified, when the callback is needed,
1930  the HAL_OSPI_RxHalfCpltCallback could be implemented in the user file
1931  */
1932 }
1933 
1940 {
1941  /* Prevent unused argument(s) compilation warning */
1942  UNUSED(hospi);
1943 
1944  /* NOTE: This function should not be modified, when the callback is needed,
1945  the HAL_OSPI_TxHalfCpltCallback could be implemented in the user file
1946  */
1947 }
1948 
1955 {
1956  /* Prevent unused argument(s) compilation warning */
1957  UNUSED(hospi);
1958 
1959  /* NOTE : This function should not be modified, when the callback is needed,
1960  the HAL_OSPI_StatusMatchCallback could be implemented in the user file
1961  */
1962 }
1963 
1970 {
1971  /* Prevent unused argument(s) compilation warning */
1972  UNUSED(hospi);
1973 
1974  /* NOTE : This function should not be modified, when the callback is needed,
1975  the HAL_OSPI_TimeOutCallback could be implemented in the user file
1976  */
1977 }
1978 
1979 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
1980 
2002 {
2003  HAL_StatusTypeDef status = HAL_OK;
2004 
2005  if(pCallback == NULL)
2006  {
2007  /* Update the error code */
2008  hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2009  return HAL_ERROR;
2010  }
2011 
2012  if(hospi->State == HAL_OSPI_STATE_READY)
2013  {
2014  switch (CallbackID)
2015  {
2016  case HAL_OSPI_ERROR_CB_ID :
2017  hospi->ErrorCallback = pCallback;
2018  break;
2019  case HAL_OSPI_ABORT_CB_ID :
2020  hospi->AbortCpltCallback = pCallback;
2021  break;
2023  hospi->FifoThresholdCallback = pCallback;
2024  break;
2026  hospi->CmdCpltCallback = pCallback;
2027  break;
2028  case HAL_OSPI_RX_CPLT_CB_ID :
2029  hospi->RxCpltCallback = pCallback;
2030  break;
2031  case HAL_OSPI_TX_CPLT_CB_ID :
2032  hospi->TxCpltCallback = pCallback;
2033  break;
2035  hospi->RxHalfCpltCallback = pCallback;
2036  break;
2038  hospi->TxHalfCpltCallback = pCallback;
2039  break;
2041  hospi->StatusMatchCallback = pCallback;
2042  break;
2043  case HAL_OSPI_TIMEOUT_CB_ID :
2044  hospi->TimeOutCallback = pCallback;
2045  break;
2047  hospi->MspInitCallback = pCallback;
2048  break;
2050  hospi->MspDeInitCallback = pCallback;
2051  break;
2052  default :
2053  /* Update the error code */
2054  hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2055  /* update return status */
2056  status = HAL_ERROR;
2057  break;
2058  }
2059  }
2060  else if (hospi->State == HAL_OSPI_STATE_RESET)
2061  {
2062  switch (CallbackID)
2063  {
2065  hospi->MspInitCallback = pCallback;
2066  break;
2068  hospi->MspDeInitCallback = pCallback;
2069  break;
2070  default :
2071  /* Update the error code */
2072  hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2073  /* update return status */
2074  status = HAL_ERROR;
2075  break;
2076  }
2077  }
2078  else
2079  {
2080  /* Update the error code */
2081  hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2082  /* update return status */
2083  status = HAL_ERROR;
2084  }
2085 
2086  return status;
2087 }
2088 
2110 {
2111  HAL_StatusTypeDef status = HAL_OK;
2112 
2113  if(hospi->State == HAL_OSPI_STATE_READY)
2114  {
2115  switch (CallbackID)
2116  {
2117  case HAL_OSPI_ERROR_CB_ID :
2119  break;
2120  case HAL_OSPI_ABORT_CB_ID :
2122  break;
2125  break;
2128  break;
2129  case HAL_OSPI_RX_CPLT_CB_ID :
2131  break;
2132  case HAL_OSPI_TX_CPLT_CB_ID :
2134  break;
2137  break;
2140  break;
2143  break;
2144  case HAL_OSPI_TIMEOUT_CB_ID :
2146  break;
2149  break;
2152  break;
2153  default :
2154  /* Update the error code */
2155  hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2156  /* update return status */
2157  status = HAL_ERROR;
2158  break;
2159  }
2160  }
2161  else if (hospi->State == HAL_OSPI_STATE_RESET)
2162  {
2163  switch (CallbackID)
2164  {
2167  break;
2170  break;
2171  default :
2172  /* Update the error code */
2173  hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2174  /* update return status */
2175  status = HAL_ERROR;
2176  break;
2177  }
2178  }
2179  else
2180  {
2181  /* Update the error code */
2182  hospi->ErrorCode |= HAL_OSPI_ERROR_INVALID_CALLBACK;
2183  /* update return status */
2184  status = HAL_ERROR;
2185  }
2186 
2187  return status;
2188 }
2189 #endif
2190 
2219 HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi)
2220 {
2221  HAL_StatusTypeDef status = HAL_OK;
2222  uint32_t state;
2223  uint32_t tickstart = HAL_GetTick();
2224 
2225  /* Check if the state is in one of the busy or configured states */
2226  state = hospi->State;
2227  if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2228  {
2229  /* Check if the DMA is enabled */
2230  if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2231  {
2232  /* Disable the DMA transfer on the OctoSPI side */
2233  CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2234 
2235  /* Disable the DMA transfer on the DMA side */
2236  status = HAL_DMA_Abort(hospi->hdma);
2237  if (status != HAL_OK)
2238  {
2239  hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2240  }
2241  }
2242 
2243  if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2244  {
2245  /* Perform an abort of the OctoSPI */
2246  SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2247 
2248  /* Wait until the transfer complete flag is set to go back in idle state */
2249  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, hospi->Timeout);
2250 
2251  if (status == HAL_OK)
2252  {
2253  /* Clear transfer complete flag */
2254  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2255 
2256  /* Wait until the busy flag is reset to go back in idle state */
2257  status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout);
2258 
2259  if (status == HAL_OK)
2260  {
2261  /* Update state */
2262  hospi->State = HAL_OSPI_STATE_READY;
2263  }
2264  }
2265  }
2266  else
2267  {
2268  /* Update state */
2269  hospi->State = HAL_OSPI_STATE_READY;
2270  }
2271  }
2272  else
2273  {
2274  status = HAL_ERROR;
2275  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2276  }
2277 
2278  /* Return function status */
2279  return status;
2280 }
2281 
2287 HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi)
2288 {
2289  HAL_StatusTypeDef status = HAL_OK;
2290  uint32_t state;
2291 
2292  /* Check if the state is in one of the busy or configured states */
2293  state = hospi->State;
2294  if (((state & OSPI_BUSY_STATE_MASK) != 0U) || ((state & OSPI_CFG_STATE_MASK) != 0U))
2295  {
2296  /* Disable all interrupts */
2297  __HAL_OSPI_DISABLE_IT(hospi, (HAL_OSPI_IT_TO | HAL_OSPI_IT_SM | HAL_OSPI_IT_FT | HAL_OSPI_IT_TC | HAL_OSPI_IT_TE));
2298 
2299  /* Update state */
2300  hospi->State = HAL_OSPI_STATE_ABORT;
2301 
2302  /* Check if the DMA is enabled */
2303  if ((hospi->Instance->CR & OCTOSPI_CR_DMAEN) != 0U)
2304  {
2305  /* Disable the DMA transfer on the OctoSPI side */
2306  CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2307 
2308  /* Disable the DMA transfer on the DMA side */
2309  hospi->hdma->XferAbortCallback = OSPI_DMAAbortCplt;
2310  if (HAL_DMA_Abort_IT(hospi->hdma) != HAL_OK)
2311  {
2312  /* Update state */
2313  hospi->State = HAL_OSPI_STATE_READY;
2314 
2315  /* Abort callback */
2316 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2317  hospi->AbortCpltCallback(hospi);
2318 #else
2320 #endif
2321  }
2322  }
2323  else
2324  {
2325  if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2326  {
2327  /* Clear transfer complete flag */
2328  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2329 
2330  /* Enable the transfer complete interrupts */
2331  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2332 
2333  /* Perform an abort of the OctoSPI */
2334  SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2335  }
2336  else
2337  {
2338  /* Update state */
2339  hospi->State = HAL_OSPI_STATE_READY;
2340 
2341  /* Abort callback */
2342 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2343  hospi->AbortCpltCallback(hospi);
2344 #else
2346 #endif
2347  }
2348  }
2349  }
2350  else
2351  {
2352  status = HAL_ERROR;
2353  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2354  }
2355 
2356  /* Return function status */
2357  return status;
2358 }
2359 
2365 HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold)
2366 {
2367  HAL_StatusTypeDef status = HAL_OK;
2368 
2369  /* Check the state */
2370  if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U)
2371  {
2372  /* Synchronize initialization structure with the new fifo threshold value */
2373  hospi->Init.FifoThreshold = Threshold;
2374 
2375  /* Configure new fifo threshold */
2376  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold-1U) << OCTOSPI_CR_FTHRES_Pos));
2377 
2378  }
2379  else
2380  {
2381  status = HAL_ERROR;
2382  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;
2383  }
2384 
2385  /* Return function status */
2386  return status;
2387 }
2388 
2394 {
2395  return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U);
2396 }
2397 
2403 HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout)
2404 {
2405  hospi->Timeout = Timeout;
2406  return HAL_OK;
2407 }
2408 
2415 {
2416  return hospi->ErrorCode;
2417 }
2418 
2425 {
2426  /* Return OSPI handle state */
2427  return hospi->State;
2428 }
2429 
2456 HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
2457 {
2458  HAL_StatusTypeDef status = HAL_OK;
2459  uint32_t instance;
2460  uint8_t index, ospi_enabled = 0U, other_instance;
2461  OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];
2462 
2463  /* Prevent unused argument(s) compilation warning */
2464  UNUSED(Timeout);
2465 
2466  /* Check the parameters of the OctoSPI IO Manager configuration structure */
2467  assert_param(IS_OSPIM_PORT(cfg->ClkPort));
2468  assert_param(IS_OSPIM_PORT(cfg->DQSPort));
2469  assert_param(IS_OSPIM_PORT(cfg->NCSPort));
2470  assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort));
2471  assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort));
2472 
2473  if (hospi->Instance == OCTOSPI1)
2474  {
2475  instance = 0U;
2476  other_instance = 1U;
2477  }
2478  else
2479  {
2480  instance = 1U;
2481  other_instance = 0U;
2482  }
2483 
2484  /**************** Get current configuration of the instances ****************/
2485  for (index = 0U; index < OSPI_NB_INSTANCE; index++)
2486  {
2487  if (OSPIM_GetConfig(index+1U, &(IOM_cfg[index])) != HAL_OK)
2488  {
2489  status = HAL_ERROR;
2490  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
2491  }
2492  }
2493 
2494  if (status == HAL_OK)
2495  {
2496  /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
2497  if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U)
2498  {
2499  CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2500  ospi_enabled |= 0x1U;
2501  }
2502  if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U)
2503  {
2504  CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2505  ospi_enabled |= 0x2U;
2506  }
2507 
2508  /***************** Deactivation of previous configuration *****************/
2509  if (IOM_cfg[instance].ClkPort != 0U)
2510  {
2511  CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN);
2512  CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN);
2513  CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN);
2514  CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
2515  CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
2516  }
2517 
2518  /********************* Deactivation of other instance *********************/
2519  if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) ||
2520  (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
2521  (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
2522  {
2523  CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN);
2524  CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN);
2525  CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN);
2526  CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
2527  CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
2528  }
2529 
2530  /******************** Activation of new configuration *********************/
2531  MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
2532  MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
2533  MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort-1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));
2534 
2535  if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
2536  {
2537  MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2538  (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U))));
2539  }
2540  else
2541  {
2542  MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2543  (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U))));
2544  }
2545 
2546  if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
2547  {
2548  MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
2549  (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos+1U))));
2550  }
2551  else
2552  {
2553  MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
2554  (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos+1U))));
2555  }
2556 
2557  /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
2558  if ((ospi_enabled & 0x1U) != 0U)
2559  {
2560  SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
2561  }
2562  if ((ospi_enabled & 0x2U) != 0U)
2563  {
2564  SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
2565  }
2566  }
2567 
2568  /* Return function status */
2569  return status;
2570 }
2571 
2584 static void OSPI_DMACplt(DMA_HandleTypeDef *hdma)
2585 {
2586  OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hdma->Parent);
2587  hospi->XferCount = 0;
2588 
2589  /* Disable the DMA transfer on the OctoSPI side */
2590  CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2591 
2592  /* Disable the DMA channel */
2593  __HAL_DMA_DISABLE(hdma);
2594 
2595  /* Enable the OSPI transfer complete Interrupt */
2596  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2597 }
2598 
2604 static void OSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma)
2605 {
2606  OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hdma->Parent);
2607  hospi->XferCount = (hospi->XferCount >> 1);
2608 
2609  if (hospi->State == HAL_OSPI_STATE_BUSY_RX)
2610  {
2611 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2612  hospi->RxHalfCpltCallback(hospi);
2613 #else
2615 #endif
2616  }
2617  else
2618  {
2619 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2620  hospi->TxHalfCpltCallback(hospi);
2621 #else
2623 #endif
2624  }
2625 }
2626 
2632 static void OSPI_DMAError(DMA_HandleTypeDef *hdma)
2633 {
2634  OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hdma->Parent);
2635  hospi->XferCount = 0;
2636  hospi->ErrorCode = HAL_OSPI_ERROR_DMA;
2637 
2638  /* Disable the DMA transfer on the OctoSPI side */
2639  CLEAR_BIT(hospi->Instance->CR, OCTOSPI_CR_DMAEN);
2640 
2641  /* Abort the OctoSPI */
2642  if (HAL_OSPI_Abort_IT(hospi) != HAL_OK)
2643  {
2644  /* Disable the interrupts */
2645  __HAL_OSPI_DISABLE_IT(hospi, HAL_OSPI_IT_TC | HAL_OSPI_IT_FT | HAL_OSPI_IT_TE);
2646 
2647  /* Update state */
2648  hospi->State = HAL_OSPI_STATE_READY;
2649 
2650  /* Error callback */
2651 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2652  hospi->ErrorCallback(hospi);
2653 #else
2654  HAL_OSPI_ErrorCallback(hospi);
2655 #endif
2656  }
2657 }
2658 
2664 static void OSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma)
2665 {
2666  OSPI_HandleTypeDef* hospi = ( OSPI_HandleTypeDef* )(hdma->Parent);
2667  hospi->XferCount = 0;
2668 
2669  /* Check the state */
2670  if (hospi->State == HAL_OSPI_STATE_ABORT)
2671  {
2672  /* DMA abort called by OctoSPI abort */
2673  if (__HAL_OSPI_GET_FLAG(hospi, HAL_OSPI_FLAG_BUSY) != RESET)
2674  {
2675  /* Clear transfer complete flag */
2676  __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC);
2677 
2678  /* Enable the transfer complete interrupts */
2679  __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TC);
2680 
2681  /* Perform an abort of the OctoSPI */
2682  SET_BIT(hospi->Instance->CR, OCTOSPI_CR_ABORT);
2683  }
2684  else
2685  {
2686  /* Update state */
2687  hospi->State = HAL_OSPI_STATE_READY;
2688 
2689  /* Abort callback */
2690 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2691  hospi->AbortCpltCallback(hospi);
2692 #else
2694 #endif
2695  }
2696  }
2697  else
2698  {
2699  /* DMA abort called due to a transfer error interrupt */
2700  /* Update state */
2701  hospi->State = HAL_OSPI_STATE_READY;
2702 
2703  /* Error callback */
2704 #if defined (USE_HAL_OSPI_REGISTER_CALLBACKS) && (USE_HAL_OSPI_REGISTER_CALLBACKS == 1U)
2705  hospi->ErrorCallback(hospi);
2706 #else
2707  HAL_OSPI_ErrorCallback(hospi);
2708 #endif
2709  }
2710 }
2711 
2721 static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag,
2722  FlagStatus State, uint32_t Tickstart, uint32_t Timeout)
2723 {
2724  /* Wait until flag is in expected state */
2725  while((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State)
2726  {
2727  /* Check for the Timeout */
2728  if (Timeout != HAL_MAX_DELAY)
2729  {
2730  if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
2731  {
2732  hospi->State = HAL_OSPI_STATE_ERROR;
2733  hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT;
2734 
2735  return HAL_ERROR;
2736  }
2737  }
2738  }
2739  return HAL_OK;
2740 }
2741 
2748 static HAL_StatusTypeDef OSPI_ConfigCmd(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
2749 {
2750  HAL_StatusTypeDef status = HAL_OK;
2751  __IO uint32_t *ccr_reg, *tcr_reg, *ir_reg, *abr_reg;
2752 
2753  /* Re-initialize the value of the functional mode */
2754  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U);
2755 
2756  /* Configure the flash ID */
2757  if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE)
2758  {
2759  MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId);
2760  }
2761 
2762  if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)
2763  {
2764  ccr_reg = &(hospi->Instance->WCCR);
2765  tcr_reg = &(hospi->Instance->WTCR);
2766  ir_reg = &(hospi->Instance->WIR);
2767  abr_reg = &(hospi->Instance->WABR);
2768  }
2769  else
2770  {
2771  ccr_reg = &(hospi->Instance->CCR);
2772  tcr_reg = &(hospi->Instance->TCR);
2773  ir_reg = &(hospi->Instance->IR);
2774  abr_reg = &(hospi->Instance->ABR);
2775  }
2776 
2777  /* Configure the CCR register with DQS and SIOO modes */
2778  *ccr_reg = (cmd->DQSMode | cmd->SIOOMode);
2779 
2780  if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE)
2781  {
2782  /* Configure the ABR register with alternate bytes value */
2783  *abr_reg = cmd->AlternateBytes;
2784 
2785  /* Configure the CCR register with alternate bytes communication parameters */
2786  MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE),
2788  }
2789 
2790  /* Configure the TCR register with the number of dummy cycles */
2791  MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles);
2792 
2793  if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2794  {
2795  if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG)
2796  {
2797  /* Configure the DLR register with the number of data */
2798  hospi->Instance->DLR = (cmd->NbData - 1U);
2799  }
2800  }
2801 
2802  if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE)
2803  {
2804  if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
2805  {
2806  if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2807  {
2808  /* ---- Command with instruction, address and data ---- */
2809 
2810  /* Configure the CCR register with all communication parameters */
2811  MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
2812  OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
2813  OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
2814  (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2815  cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize |
2816  cmd->DataMode | cmd->DataDtrMode));
2817  }
2818  else
2819  {
2820  /* ---- Command with instruction and address ---- */
2821 
2822  /* Configure the CCR register with all communication parameters */
2823  MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
2824  OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
2825  (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2826  cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
2827 
2828  /* The DHQC bit is linked with DDTR bit which should be activated */
2829  if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
2830  (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
2831  {
2832  MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
2833  }
2834  }
2835 
2836  /* Configure the IR register with the instruction value */
2837  *ir_reg = cmd->Instruction;
2838 
2839  /* Configure the AR register with the address value */
2840  hospi->Instance->AR = cmd->Address;
2841  }
2842  else
2843  {
2844  if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2845  {
2846  /* ---- Command with instruction and data ---- */
2847 
2848  /* Configure the CCR register with all communication parameters */
2849  MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE |
2850  OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
2851  (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize |
2852  cmd->DataMode | cmd->DataDtrMode));
2853  }
2854  else
2855  {
2856  /* ---- Command with only instruction ---- */
2857 
2858  /* Configure the CCR register with all communication parameters */
2859  MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE),
2860  (cmd->InstructionMode | cmd->InstructionDtrMode | cmd->InstructionSize));
2861 
2862  /* The DHQC bit is linked with DDTR bit which should be activated */
2863  if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) &&
2864  (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE))
2865  {
2866  MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE);
2867  }
2868  }
2869 
2870  /* Configure the IR register with the instruction value */
2871  *ir_reg = cmd->Instruction;
2872 
2873  }
2874  }
2875  else
2876  {
2877  if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE)
2878  {
2879  if (cmd->DataMode != HAL_OSPI_DATA_NONE)
2880  {
2881  /* ---- Command with address and data ---- */
2882 
2883  /* Configure the CCR register with all communication parameters */
2884  MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE |
2885  OCTOSPI_CCR_DMODE | OCTOSPI_CCR_DDTR),
2886  (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize |
2887  cmd->DataMode | cmd->DataDtrMode));
2888  }
2889  else
2890  {
2891  /* ---- Command with only address ---- */
2892 
2893  /* Configure the CCR register with all communication parameters */
2894  MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE),
2895  (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize));
2896  }
2897 
2898  /* Configure the AR register with the instruction value */
2899  hospi->Instance->AR = cmd->Address;
2900  }
2901  else
2902  {
2903  /* ---- Invalid command configuration (no instruction, no address) ---- */
2904  status = HAL_ERROR;
2905  hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
2906  }
2907  }
2908 
2909  /* Return function status */
2910  return status;
2911 }
2912 
2919 static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg)
2920 {
2921  HAL_StatusTypeDef status = HAL_OK;
2922  uint32_t reg, value = 0U;
2923  uint32_t index;
2924 
2925  if ((instance_nb == 0U) || (instance_nb > OSPI_NB_INSTANCE) || (cfg == NULL))
2926  {
2927  /* Invalid parameter -> error returned */
2928  status = HAL_ERROR;
2929  }
2930  else
2931  {
2932  /* Initialize the structure */
2933  cfg->ClkPort = 0U;
2934  cfg->DQSPort = 0U;
2935  cfg->NCSPort = 0U;
2936  cfg->IOLowPort = 0U;
2937  cfg->IOHighPort = 0U;
2938 
2939  if (instance_nb == 2U)
2940  {
2941  value = (OCTOSPIM_PCR_CLKSRC | OCTOSPIM_PCR_DQSSRC | OCTOSPIM_PCR_NCSSRC | OCTOSPIM_PCR_IOLSRC_1 | OCTOSPIM_PCR_IOHSRC_1);
2942  }
2943 
2944  /* Get the information about the instance */
2945  for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++)
2946  {
2947  reg = OCTOSPIM->PCR[index];
2948 
2949  if ((reg & OCTOSPIM_PCR_CLKEN) != 0U)
2950  {
2951  /* The clock is enabled on this port */
2952  if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC))
2953  {
2954  /* The clock correspond to the instance passed as parameter */
2955  cfg->ClkPort = index+1U;
2956  }
2957  }
2958 
2959  if ((reg & OCTOSPIM_PCR_DQSEN) != 0U)
2960  {
2961  /* The DQS is enabled on this port */
2962  if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC))
2963  {
2964  /* The DQS correspond to the instance passed as parameter */
2965  cfg->DQSPort = index+1U;
2966  }
2967  }
2968 
2969  if ((reg & OCTOSPIM_PCR_NCSEN) != 0U)
2970  {
2971  /* The nCS is enabled on this port */
2972  if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC))
2973  {
2974  /* The nCS correspond to the instance passed as parameter */
2975  cfg->NCSPort = index+1U;
2976  }
2977  }
2978 
2979  if ((reg & OCTOSPIM_PCR_IOLEN) != 0U)
2980  {
2981  /* The IO Low is enabled on this port */
2982  if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1))
2983  {
2984  /* The IO Low correspond to the instance passed as parameter */
2985  if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U)
2986  {
2987  cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index+1U));
2988  }
2989  else
2990  {
2991  cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index+1U));
2992  }
2993  }
2994  }
2995 
2996  if ((reg & OCTOSPIM_PCR_IOHEN) != 0U)
2997  {
2998  /* The IO High is enabled on this port */
2999  if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1))
3000  {
3001  /* The IO High correspond to the instance passed as parameter */
3002  if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U)
3003  {
3004  cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index+1U));
3005  }
3006  else
3007  {
3008  cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index+1U));
3009  }
3010  }
3011  }
3012  }
3013  }
3014 
3015  /* Return function status */
3016  return status;
3017 }
3018 
3027 #endif /* HAL_OSPI_MODULE_ENABLED */
3028 
3037 #endif /* OCTOSPI || OCTOSPI1 || OCTOSPI2 */
3038 
3039 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
HAL_OSPI_CallbackIDTypeDef
HAL OSPI Callback ID enumeration definition.
HAL_StatusTypeDef HAL_OSPI_Receive_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
Receive an amount of data in non-blocking mode with interrupt.
uint32_t HAL_OSPI_GetError(OSPI_HandleTypeDef *hospi)
Return the OSPI error code.
HAL_StatusTypeDef HAL_OSPI_Receive_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
Receive an amount of data in non-blocking mode with DMA.
void(* XferAbortCallback)(struct __DMA_HandleTypeDef *hdma)
void(* TimeOutCallback)(struct __OSPI_HandleTypeDef *hospi)
HAL OSPI IO Manager Configuration structure definition.
HAL_StatusTypeDef HAL_OSPI_AutoPolling(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
Configure the OSPI Automatic Polling Mode in blocking mode.
HAL_StatusTypeDef HAL_OSPI_UnRegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID)
Unregister a User OSPI Callback OSPI Callback is redirected to the weak (surcharged) predefined callb...
HAL OSPI Hyperbus Command Structure definition.
void HAL_OSPI_StatusMatchCallback(OSPI_HandleTypeDef *hospi)
Status Match callback.
void(* RxHalfCpltCallback)(struct __OSPI_HandleTypeDef *hospi)
void(* FifoThresholdCallback)(struct __OSPI_HandleTypeDef *hospi)
hrtc State
void(* CmdCpltCallback)(struct __OSPI_HandleTypeDef *hospi)
void(* MspDeInitCallback)(struct __OSPI_HandleTypeDef *hospi)
DMA handle Structure definition.
HAL_StatusTypeDef HAL_OSPI_HyperbusCfg(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCfgTypeDef *cfg, uint32_t Timeout)
Configure the Hyperbus parameters.
uint32_t HAL_OSPI_GetState(OSPI_HandleTypeDef *hospi)
Return the OSPI handle state.
void(* XferCpltCallback)(struct __DMA_HandleTypeDef *hdma)
void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi)
Command completed callback.
HAL_StatusTypeDef HAL_OSPI_AutoPolling_IT(OSPI_HandleTypeDef *hospi, OSPI_AutoPollingTypeDef *cfg)
Configure the OSPI Automatic Polling Mode in non-blocking mode.
HAL_StatusTypeDef HAL_OSPI_HyperbusCmd(OSPI_HandleTypeDef *hospi, OSPI_HyperbusCmdTypeDef *cmd, uint32_t Timeout)
Set the Hyperbus command configuration.
HAL OSPI Handle Structure definition.
This file contains all the functions prototypes for the HAL module driver.
HAL_StatusTypeDef HAL_OSPI_MemoryMapped(OSPI_HandleTypeDef *hospi, OSPI_MemoryMappedTypeDef *cfg)
Configure the Memory Mapped mode.
HAL_StatusTypeDef HAL_OSPI_Transmit(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
Transmit an amount of data in blocking mode.
HAL_StatusTypeDef HAL_OSPI_Command(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd, uint32_t Timeout)
Set the command configuration.
HAL_StatusTypeDef HAL_OSPI_Receive(OSPI_HandleTypeDef *hospi, uint8_t *pData, uint32_t Timeout)
Receive an amount of data in blocking mode.
void HAL_OSPI_IRQHandler(OSPI_HandleTypeDef *hospi)
Handle OSPI interrupt request.
void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi)
Tx Transfer completed callback.
uint32_t HAL_GetTick(void)
Provide a tick value in millisecond.
DMA_Channel_TypeDef * Instance
void(* RxCpltCallback)(struct __OSPI_HandleTypeDef *hospi)
void(* XferErrorCallback)(struct __DMA_HandleTypeDef *hdma)
OSPI_InitTypeDef Init
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
Aborts the DMA Transfer in Interrupt mode.
void(* XferHalfCpltCallback)(struct __DMA_HandleTypeDef *hdma)
HAL_StatusTypeDef HAL_OSPI_Transmit_DMA(OSPI_HandleTypeDef *hospi, uint8_t *pData)
Send an amount of data in non-blocking mode with DMA.
DMA_InitTypeDef Init
HAL OSPI Hyperbus Configuration Structure definition.
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
Start the DMA Transfer with interrupt enabled.
CLEAR_BIT(hrtc->Instance->CR, RTC_CR_WUTE)
void(* TxHalfCpltCallback)(struct __OSPI_HandleTypeDef *hospi)
HAL_StatusTypeDef HAL_OSPI_SetTimeout(OSPI_HandleTypeDef *hospi, uint32_t Timeout)
Set OSPI timeout.
void HAL_OSPI_FifoThresholdCallback(OSPI_HandleTypeDef *hospi)
FIFO Threshold callback.
HAL OSPI Regular Command Structure definition.
return HAL_OK
uint32_t HAL_OSPI_GetFifoThreshold(OSPI_HandleTypeDef *hospi)
Get OSPI Fifo threshold.
HAL_StatusTypeDef HAL_OSPI_Abort_IT(OSPI_HandleTypeDef *hospi)
Abort the current transmission (non-blocking function)
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
Abort the DMA Transfer.
void HAL_OSPI_TimeOutCallback(OSPI_HandleTypeDef *hospi)
Timeout callback.
void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi)
Initialize the OSPI MSP.
HAL_StatusTypeDef HAL_OSPI_Transmit_IT(OSPI_HandleTypeDef *hospi, uint8_t *pData)
Send an amount of data in non-blocking mode with interrupt.
void(* StatusMatchCallback)(struct __OSPI_HandleTypeDef *hospi)
HAL_StatusTypeDef HAL_OSPI_Init(OSPI_HandleTypeDef *hospi)
Initialize the OSPI mode according to the specified parameters in the OSPI_InitTypeDef and initialize...
HAL_StatusTypeDef HAL_OSPI_SetFifoThreshold(OSPI_HandleTypeDef *hospi, uint32_t Threshold)
Set OSPI Fifo threshold.
HAL_StatusTypeDef HAL_OSPI_Abort(OSPI_HandleTypeDef *hospi)
Abort the current transmission.
void HAL_OSPI_TxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
Tx Half Transfer completed callback.
HAL_StatusTypeDef HAL_OSPI_Command_IT(OSPI_HandleTypeDef *hospi, OSPI_RegularCmdTypeDef *cmd)
Set the command configuration in interrupt mode.
void(* AbortCpltCallback)(struct __OSPI_HandleTypeDef *hospi)
void(* pOSPI_CallbackTypeDef)(OSPI_HandleTypeDef *hospi)
HAL OSPI Callback pointer definition.
HAL OSPI Auto Polling mode configuration structure definition.
void(* TxCpltCallback)(struct __OSPI_HandleTypeDef *hospi)
void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi)
Rx Transfer completed callback.
void(* ErrorCallback)(struct __OSPI_HandleTypeDef *hospi)
void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef *hospi)
DeInitialize the OSPI MSP.
HAL_StatusTypeDef HAL_OSPI_RegisterCallback(OSPI_HandleTypeDef *hospi, HAL_OSPI_CallbackIDTypeDef CallbackID, pOSPI_CallbackTypeDef pCallback)
Register a User OSPI Callback To be used instead of the weak (surcharged) predefined callback...
void HAL_OSPI_RxHalfCpltCallback(OSPI_HandleTypeDef *hospi)
Rx Half Transfer completed callback.
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
HAL_StatusTypeDef HAL_OSPI_DeInit(OSPI_HandleTypeDef *hospi)
De-Initialize the OSPI peripheral.
HAL OSPI Memory Mapped mode configuration structure definition.
HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
Configure the OctoSPI IO manager.
OCTOSPI_TypeDef * Instance
void(* MspInitCallback)(struct __OSPI_HandleTypeDef *hospi)
void HAL_OSPI_AbortCpltCallback(OSPI_HandleTypeDef *hospi)
Abort completed callback.
assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock))
DMA_HandleTypeDef * hdma
void HAL_OSPI_ErrorCallback(OSPI_HandleTypeDef *hospi)
Transfer Error callback.