static int stm32_opampconfig()

in arch/arm/src/stm32/stm32_opamp.c [561:1127]


static int stm32_opampconfig(struct stm32_opamp_s *priv)
{
  uint32_t regval = 0;
  int index;

  /* Get OPAMP index */

  switch (priv->csr)
    {
#ifdef CONFIG_STM32_OPAMP1
    case STM32_OPAMP1_CSR:
      index = 1;
      break;
#endif

#ifdef CONFIG_STM32_OPAMP2
    case STM32_OPAMP2_CSR:
      index = 2;
      break;
#endif

#ifdef CONFIG_STM32_OPAMP3
    case STM32_OPAMP3_CSR:
      index = 3;
      break;
#endif

#ifdef CONFIG_STM32_OPAMP4
    case STM32_OPAMP4_CSR:
      index = 4;
      break;
#endif

    default:
      return -EINVAL;
    }

  /* Configure non inverting input */

  switch (index)
    {
#ifdef CONFIG_STM32_OPAMP1
    case 1:
      {
        switch (priv->vp_sel)
          {
          case OPAMP1_VPSEL_PA7:
            stm32_configgpio(GPIO_OPAMP1_VINP_1);
            regval |= OPAMP_CSR_VPSEL_PA7;
            break;

          case OPAMP1_VPSEL_PA5:
            stm32_configgpio(GPIO_OPAMP1_VINP_2);
            regval |= OPAMP_CSR_VPSEL_PA5;
            break;

          case OPAMP1_VPSEL_PA3:
            stm32_configgpio(GPIO_OPAMP1_VINP_3);
            regval |= OPAMP_CSR_VPSEL_PA3;
            break;

          case OPAMP1_VPSEL_PA1:
            stm32_configgpio(GPIO_OPAMP1_VINP_4);
            regval |= OPAMP_CSR_VPSEL_PA1;
            break;

          default:
            return -EINVAL;
          }
        break;
      }
#endif

#ifdef CONFIG_STM32_OPAMP2
    case 2:
      {
        switch (priv->vp_sel)
          {
#ifndef CONFIG_STM32_STM32F33XX
          case OPAMP2_VPSEL_PD14:
            stm32_configgpio(GPIO_OPAMP2_VINP_1);
            regval |= OPAMP_CSR_VPSEL_PD14;
            break;
#endif
          case OPAMP2_VPSEL_PB14:
            stm32_configgpio(GPIO_OPAMP2_VINP_2);
            regval |= OPAMP_CSR_VPSEL_PB14;
            break;

          case OPAMP2_VPSEL_PB0:
            stm32_configgpio(GPIO_OPAMP2_VINP_3);
            regval |= OPAMP_CSR_VPSEL_PB0;
            break;

          case OPAMP2_VPSEL_PA7:
            stm32_configgpio(GPIO_OPAMP2_VINP_4);
            regval |= OPAMP_CSR_VPSEL_PA7;
            break;

          default:
            return -EINVAL;
          }
        break;
      }
#endif

#ifdef CONFIG_STM32_OPAMP3
    case 3:
      {
        switch (priv->vp_sel)
          {
          case OPAMP3_VPSEL_PB13:
            stm32_configgpio(GPIO_OPAMP3_VINP_1);
            regval |= OPAMP_CSR_VPSEL_PB13;
            break;

          case OPAMP3_VPSEL_PA5:
            stm32_configgpio(GPIO_OPAMP3_VINP_2);
            regval |= OPAMP_CSR_VPSEL_PA5;
            break;

          case OPAMP3_VPSEL_PA1:
            stm32_configgpio(GPIO_OPAMP3_VINP_3);
            regval |= OPAMP_CSR_VPSEL_PA1;
            break;

          case OPAMP3_VPSEL_PB0:
            stm32_configgpio(GPIO_OPAMP3_VINP_4);
            regval |= OPAMP_CSR_VPSEL_PB0;
            break;

          default:
            return -EINVAL;
          }
        break;
      }
#endif

#ifdef CONFIG_STM32_OPAMP4
    case 4:
      {
        switch (priv->vp_sel)
          {
          case OPAMP4_VPSEL_PD11:
            stm32_configgpio(GPIO_OPAMP4_VINP_1);
            regval |= OPAMP_CSR_VPSEL_PD11;
            break;

          case OPAMP4_VPSEL_PB11:
            stm32_configgpio(GPIO_OPAMP4_VINP_2);
            regval |= OPAMP_CSR_VPSEL_PB11;
            break;

          case OPAMP4_VPSEL_PA4:
            stm32_configgpio(GPIO_OPAMP4_VINP_3);
            regval |= OPAMP_CSR_VPSEL_PA4;
            break;

          case OPAMP4_VPSEL_PB13:
            stm32_configgpio(GPIO_OPAMP4_VINP_4;
            regval |= OPAMP_CSR_VPSEL_PB13;
            break;

          default:
            return -EINVAL;
          }
        break;
      }
#endif

    default:
      return -EINVAL;
    }

  /* Configure inverting input */

    switch (index)
    {
#ifdef CONFIG_STM32_OPAMP1
    case 1:
      {
        switch (priv->vm_sel)
          {
          case OPAMP1_VSEL_PC5:
            stm32_configgpio(GPIO_OPAMP1_VINM_1);
            regval |= OPAMP_CSR_VMSEL_PC5;
            break;

          case OPAMP1_VMSEL_PA3:
            stm32_configgpio(GPIO_OPAMP1_VINM_2);
            regval |= OPAMP_CSR_VMSEL_PA3;
            break;

          case OPAMP1_VMSEL_PGAMODE:
            regval |= OPAMP_CSR_VMSEL_PGA;
            break;

          case OPAMP1_VMSEL_FOLLOWER:
            regval |= OPAMP_CSR_VMSEL_FOLLOWER;
            break;

          default:
            return -EINVAL;
          }
        break;
      }
#endif

#ifdef CONFIG_STM32_OPAMP2
    case 2:
      {
        switch (priv->vm_sel)
          {
          case OPAMP2_VMSEL_PC5:
            stm32_configgpio(GPIO_OPAMP2_VINM_1);
            regval |= OPAMP_CSR_VMSEL_PC5;
            break;

          case OPAMP2_VMSEL_PA5:
            stm32_configgpio(GPIO_OPAMP2_VINM_2);
            regval |= OPAMP_CSR_VMSEL_PA5;
            break;

          case OPAMP2_VMSEL_PGAMODE:
            regval |= OPAMP_CSR_VMSEL_PGA;
            break;

          case OPAMP2_VMSEL_FOLLOWER:
            regval |= OPAMP_CSR_VMSEL_FOLLOWER;
            break;

          default:
            return -EINVAL;
          }
        break;
      }
#endif

#ifdef CONFIG_STM32_OPAMP3
    case 3:
      {
        switch (priv->vm_sel)
          {
          case OPAMP3_VMSEL_PB10:
            stm32_configgpio(GPIO_OPAMP3_VINM_1);
            regval |= OPAMP_CSR_VMSEL_PB10;
            break;

          case OPAMP3_VMSEL_PB2:
            stm32_configgpio(GPIO_OPAMP3_VINM_2);
            regval |= OPAMP_CSR_VMSEL_PB2;
            break;

          case OPAMP3_VMSEL_PGAMODE:
            regval |= OPAMP_CSR_VMSEL_PGA;
            break;

          case OPAMP3_VMSEL_FOLLOWER:
            regval |= OPAMP_CSR_VMSEL_FOLLOWER;
            break;

          default:
            return -EINVAL;
          }
        break;
      }
#endif

#ifdef CONFIG_STM32_OPAMP4
    case 4:
      {
        switch (priv->vm_sel)
          {
          case OPAMP4_VMSEL_PB10:
            stm32_configgpio(GPIO_OPAMP4_VINM_1);
            regval |= OPAMP_CSR_VMSEL_PB10;
            break;

          case OPAMP4_VMSEL_PD8:
            stm32_configgpio(GPIO_OPAMP4_VINM_2);
            regval |= OPAMP_CSR_VMSEL_PD8;
            break;

          case OPAMP4_VMSEL_PGAMODE:
            regval |= OPAMP_CSR_VMSEL_PGA;
            break;

          case OPAMP4_VMSEL_FOLLOWER:
            regval |= OPAMP_CSR_VMSEL_FOLLOWER;
            break;

          default:
            return -EINVAL;
          }
        break;
      }
#endif

    default:
      return -EINVAL;
    }

    if (priv->mux == 1)
      {
        /* Enable Timer controlled Mux mode */

        regval |= OPAMP_CSR_TCMEN;

        /* Configure non inverting secondary input */

        switch (index)
          {
#ifdef CONFIG_STM32_OPAMP1
          case 1:
            {
              switch (priv->vps_sel)
                {
                case OPAMP1_VPSEL_PA7:
                  stm32_configgpio(GPIO_OPAMP1_VINP_1);
                  regval |= OPAMP_CSR_VPSSEL_PA7;
                  break;

                case OPAMP1_VPSEL_PA5:
                  stm32_configgpio(GPIO_OPAMP1_VINP_2);
                  regval |= OPAMP_CSR_VPSSEL_PA5;
                  break;

                case OPAMP1_VPSEL_PA3:
                  stm32_configgpio(GPIO_OPAMP1_VINP_3);
                  regval |= OPAMP_CSR_VPSSEL_PA3;
                  break;

                case OPAMP1_VPSEL_PA1:
                  stm32_configgpio(GPIO_OPAMP1_VINP_4);
                  regval |= OPAMP_CSR_VPSSEL_PA1;
                  break;

                default:
                  return -EINVAL;
                }
              break;
            }
#endif

#ifdef CONFIG_STM32_OPAMP2
          case 2:
            {
              switch (priv->vps_sel)
                {
#ifndef CONFIG_STM32_STM32F33XX
                case OPAMP2_VPSEL_PD14:
                  stm32_configgpio(GPIO_OPAMP2_VINP_1);
                  regval |= OPAMP_CSR_VPSSEL_PD14;
                  break;
#endif
                case OPAMP2_VPSEL_PB14:
                  stm32_configgpio(GPIO_OPAMP2_VINP_2);
                  regval |= OPAMP_CSR_VPSSEL_PB14;
                  break;

                case OPAMP2_VPSEL_PB0:
                  stm32_configgpio(GPIO_OPAMP2_VINP_3);
                  regval |= OPAMP_CSR_VPSSEL_PB0;
                  break;

                case OPAMP2_VPSEL_PA7:
                  stm32_configgpio(GPIO_OPAMP2_VINP_4);
                  regval |= OPAMP_CSR_VPSSEL_PA7;
                  break;

                default:
                  return -EINVAL;
                }
              break;
            }
#endif

#ifdef CONFIG_STM32_OPAMP3
          case 3:
            {
              switch (priv->vps_sel)
                {
                case OPAMP3_VPSEL_PB13:
                  stm32_configgpio(GPIO_OPAMP3_VINP_1);
                  regval |= OPAMP_CSR_VPSSEL_PB13;
                  break;

                case OPAMP3_VPSEL_PA5:
                  stm32_configgpio(GPIO_OPAMP3_VINP_2);
                  regval |= OPAMP_CSR_VPSSEL_PA5;
                  break;

                case OPAMP3_VPSEL_PA1:
                  stm32_configgpio(GPIO_OPAMP3_VINP_3);
                  regval |= OPAMP_CSR_VPSSEL_PA1;
                  break;

                case OPAMP3_VPSEL_PB0:
                  stm32_configgpio(GPIO_OPAMP3_VINP_4);
                  regval |= OPAMP_CSR_VPSSEL_PB0;
                  break;

                default:
                  return -EINVAL;
                }
              break;
            }
#endif

#ifdef CONFIG_STM32_OPAMP4
          case 4:
            {
              switch (priv->vps_sel)
                {
                case OPAMP4_VPSEL_PD11:
                  stm32_configgpio(GPIO_OPAMP4_VINP_1);
                  regval |= OPAMP_CSR_VPSSEL_PD11;
                  break;

                case OPAMP4_VPSEL_PB11:
                  stm32_configgpio(GPIO_OPAMP4_VINP_2);
                  regval |= OPAMP_CSR_VPSSEL_PB11;
                  break;

                case OPAMP4_VPSEL_PA4:
                  stm32_configgpio(GPIO_OPAMP4_VINP_3);
                  regval |= OPAMP_CSR_VPSSEL_PA4;
                  break;

                case OPAMP4_VPSEL_PB13:
                  stm32_configgpio(GPIO_OPAMP4_VINP_4);
                  regval |= OPAMP_CSR_VPSSEL_PB13;
                  break;

                default:
                  return -EINVAL;
                }
              break;
            }
#endif

              default:
                return -EINVAL;
            }

            /* Configure inverting secondary input */

            switch (index)
              {
#ifdef CONFIG_STM32_OPAMP1
              case 1:
                {
                  switch (priv->vms_sel)
                    {
                    case OPAMP1_VSEL_PC5:
                      stm32_configgpio(GPIO_OPAMP1_VINM_1);
                      regval &= ~OPAMP_CSR_VMSSEL;
                      break;

                    case OPAMP1_VMSEL_PA3:
                      stm32_configgpio(GPIO_OPAMP1_VINM_2);
                      regval |= OPAMP_CSR_VMSSEL;
                      break;

                    default:
                      return -EINVAL;
                    }
                  break;
                }
#endif

#ifdef CONFIG_STM32_OPAMP2
              case 2:
                {
                  switch (priv->vms_sel)
                    {
                    case OPAMP2_VMSEL_PC5:
                      stm32_configgpio(GPIO_OPAMP2_VINM_1);
                      regval &= ~OPAMP_CSR_VMSSEL;
                      break;

                    case OPAMP2_VMSEL_PA5:
                      stm32_configgpio(GPIO_OPAMP2_VINM_2);
                      regval |= OPAMP_CSR_VMSSEL;
                      break;

                    default:
                      return -EINVAL;
                    }
                  break;
                }
#endif

#ifdef CONFIG_STM32_OPAMP3
              case 3:
                {
                  switch (priv->vms_sel)
                    {
                    case OPAMP3_VMSEL_PB10:
                      stm32_configgpio(GPIO_OPAMP3_VINM_1);
                      regval &= ~OPAMP_CSR_VMSSEL;
                      break;

                    case OPAMP3_VMSEL_PB2:
                      stm32_configgpio(GPIO_OPAMP3_VINM_2);
                      regval |= OPAMP_CSR_VMSSEL;
                      break;

                    default:
                      return -EINVAL;
                    }
                  break;
                }
#endif

#ifdef CONFIG_STM32_OPAMP4
              case 4:
                {
                  switch (priv->vms_sel)
                    {
                    case OPAMP4_VMSEL_PB10:
                      stm32_configgpio(GPIO_OPAMP4_VINM_1);
                      regval &= ~OPAMP_CSR_VMSSEL;
                      break;

                    case OPAMP4_VMSEL_PD8:
                      stm32_configgpio(GPIO_OPAMP4_VINM_2);
                      regval |= OPAMP_CSR_VMSSEL;
                      break;

                    default:
                      return -EINVAL;
                    }
                  break;
                }
#endif

              default:
                return -EINVAL;
              }
          }

    /* Save CSR register */

    opamp_putreg_csr(priv, regval);

    /* Configure default gain in PGA mode */

    stm32_opampgain_set(priv, priv->gain);

    /* Enable OPAMP */

    stm32_opampenable(priv, true);

    /* TODO: OPAMP user calibration */

    /* stm32_opampcalibrate(priv); */

    /* Lock OPAMP if needed */

    if (priv->lock == OPAMP_LOCK_RO)
      {
        stm32_opamplock(priv, true);
      }

    return OK;
}