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