HAL_StatusTypeDef HAL_OSPIM_Config()

in Drivers/STM32U5xx_HAL/Src/stm32u5xx_hal_ospi.c [2606:2852]


HAL_StatusTypeDef HAL_OSPIM_Config(OSPI_HandleTypeDef *hospi, OSPIM_CfgTypeDef *cfg, uint32_t Timeout)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t instance;
  uint8_t index;
  uint8_t ospi_enabled = 0U;
  uint8_t other_instance;
  OSPIM_CfgTypeDef IOM_cfg[OSPI_NB_INSTANCE];

  /* Prevent unused argument(s) compilation warning */
  UNUSED(Timeout);

  /* Check the parameters of the OctoSPI IO Manager configuration structure */
  assert_param(IS_OSPIM_PORT(cfg->ClkPort));
  assert_param(IS_OSPIM_DQS_PORT(cfg->DQSPort));
  assert_param(IS_OSPIM_PORT(cfg->NCSPort));
  assert_param(IS_OSPIM_IO_PORT(cfg->IOLowPort));
  assert_param(IS_OSPIM_IO_PORT(cfg->IOHighPort));

  if (hospi->Instance == OCTOSPI1)
  {
    instance = 0U;
    other_instance = 1U;
  }
  else
  {
    instance = 1U;
    other_instance = 0U;
  }

  /**************** Get current configuration of the instances ****************/
  for (index = 0U; index < OSPI_NB_INSTANCE; index++)
  {
    if (OSPIM_GetConfig(index + 1U, &(IOM_cfg[index])) != HAL_OK)
    {
      status = HAL_ERROR;
      hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM;
    }
  }

  if (status == HAL_OK)
  {
    /********** Disable both OctoSPI to configure OctoSPI IO Manager **********/
    if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U)
    {
      CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
      ospi_enabled |= 0x1U;
    }
    if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U)
    {
      CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
      ospi_enabled |= 0x2U;
    }

    /***************** Deactivation of previous configuration *****************/
    CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
    if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
    {
      /* De-multiplexing should be performed */
      CLEAR_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);

      if (other_instance == 1U)
      {
        SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKSRC);
        if (IOM_cfg[other_instance].DQSPort != 0U)
        {
          SET_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSSRC);
        }
        if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
        {
          SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                  OCTOSPIM_PCR_IOLSRC_1);
        }
        if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
        {
          SET_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                  OCTOSPIM_PCR_IOHSRC_1);
        }
      }
    }
    else
    {
      if (IOM_cfg[instance].ClkPort != 0U)
      {
        CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
        if (IOM_cfg[instance].DQSPort != 0U)
        {
          CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
        }
        if (IOM_cfg[instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
        {
          CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN);
        }
        if (IOM_cfg[instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
        {
          CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN);
        }
      }
    }

    /********************* Deactivation of other instance *********************/
    if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort)     ||
        (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) ||
        (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
    {
      if ((cfg->ClkPort   == IOM_cfg[other_instance].ClkPort)   &&
          (cfg->DQSPort    == IOM_cfg[other_instance].DQSPort)  &&
          (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) &&
          (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort))
      {
        /* Multiplexing should be performed */
        SET_BIT(OCTOSPIM->CR, OCTOSPIM_CR_MUXEN);
      }
      else
      {
        CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort - 1U)], OCTOSPIM_PCR_CLKEN);
        if (IOM_cfg[other_instance].DQSPort != 0U)
        {
          CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort - 1U)], OCTOSPIM_PCR_DQSEN);
        }
        CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort - 1U)], OCTOSPIM_PCR_NCSEN);
        if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE)
        {
          CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                    OCTOSPIM_PCR_IOLEN);
        }
        if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE)
        {
          CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                    OCTOSPIM_PCR_IOHEN);
        }
      }
    }

    /******************** Activation of new configuration *********************/
    MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort - 1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC),
               (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos)));

    if (((cfg->Req2AckTime) >= 1U) && ((cfg->Req2AckTime) <= 256U))
    {
      if ((cfg->Req2AckTime - 1U) > ((OCTOSPIM->CR & OCTOSPIM_CR_REQ2ACK_TIME) >> OCTOSPIM_CR_REQ2ACK_TIME_Pos))
      {
        MODIFY_REG(OCTOSPIM->CR, OCTOSPIM_CR_REQ2ACK_TIME, ((cfg->Req2AckTime - 1U) << OCTOSPIM_CR_REQ2ACK_TIME_Pos));
      }
      else
      {
        /* Nothing to do */
      }
    }

    if ((OCTOSPIM->CR & OCTOSPIM_CR_MUXEN) != 0U)
    {
      MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), OCTOSPIM_PCR_CLKEN);
      if (cfg->DQSPort != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), OCTOSPIM_PCR_DQSEN);
      }

      if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), OCTOSPIM_PCR_IOLEN);
      }
      else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), OCTOSPIM_PCR_IOHEN);
      }
      else
      {
        /* Nothing to do */
      }

      if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0));
      }
      else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0));
      }
      else
      {
        /* Nothing to do */
      }
    }
    else
    {
      MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort - 1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC),
                 (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos)));
      if (cfg->DQSPort != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort - 1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC),
                   (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos)));
      }

      if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
                   (OCTOSPIM_PCR_IOLEN | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
      }
      else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
                   (OCTOSPIM_PCR_IOHEN | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
      }
      else
      {
        /* Nothing to do */
      }

      if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC),
                   (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC_0 | (instance << (OCTOSPIM_PCR_IOLSRC_Pos + 1U))));
      }
      else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE)
      {
        MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort - 1U)& OSPI_IOM_PORT_MASK)],
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC),
                   (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC_0 | (instance << (OCTOSPIM_PCR_IOHSRC_Pos + 1U))));
      }
      else
      {
        /* Nothing to do */
      }
    }

    /******* Re-enable both OctoSPI after configure OctoSPI IO Manager ********/
    if ((ospi_enabled & 0x1U) != 0U)
    {
      SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN);
    }
    if ((ospi_enabled & 0x2U) != 0U)
    {
      SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN);
    }
  }

  /* Return function status */
  return status;
}