STM32L4 COMP: Port from Motorola MDK.

This commit is contained in:
Gregory Nutt 2017-02-19 11:33:35 -06:00
parent e61ded4a14
commit 4033953878
7 changed files with 771 additions and 18 deletions

View File

@ -45,6 +45,7 @@ config STM32L4_STM32L4X3
select STM32L4_HAVE_USART3
select STM32L4_HAVE_LPTIM1
select STM32L4_HAVE_LPTIM2
select STM32L4_HAVE_COMP
select STM32L4_HAVE_SAI1
select STM32L4_HAVE_SAI2
@ -58,6 +59,7 @@ config STM32L4_STM32L4X6
select STM32L4_HAVE_UART5
select STM32L4_HAVE_LPTIM1
select STM32L4_HAVE_LPTIM2
select STM32L4_HAVE_COMP
select STM32L4_HAVE_SAI1
select STM32L4_HAVE_SAI2
@ -142,6 +144,10 @@ config STM32L4_HAVE_LPTIM2
bool
default n
config STM32L4_HAVE_COMP
bool
default n
config STM32L4_HAVE_SAI1
bool
default n
@ -619,13 +625,20 @@ config STM32L4_TIM17
bool "TIM17"
default n
config STM32L4_COMP
bool "COMP"
default n
depends on STM32L4_HAVE_COMP
config STM32L4_SAI1
bool "SAI1"
default n
depends on STM32L4_HAVE_SAI1
config STM32L4_SAI2
bool "SAI2"
default n
depends on STM32L4_HAVE_SAI2
config STM32L4_DFSDM
bool "DFSDM"

View File

@ -187,6 +187,10 @@ ifeq ($(CONFIG_DEBUG_FEATURES),y)
CHIP_CSRCS += stm32l4_dumpgpio.c
endif
ifeq ($(CONFIG_STM32L4_COMP),y)
CHIP_CSRCS += stm32l4_comp.c stm32l4_exti_comp.c
endif
ifeq ($(CONFIG_STM32L4_RNG),y)
CHIP_CSRCS += stm32l4_rng.c
endif

View File

@ -69,44 +69,47 @@
# define COMP_CSR_INMSEL_VREF (3 << COMP_CSR_INMSEL_SHIFT) /* VREFINT */
# define COMP_CSR_INMSEL_DAC1 (4 << COMP_CSR_INMSEL_SHIFT) /* DAC Channel1 */
# define COMP_CSR_INMSEL_DAC2 (5 << COMP_CSR_INMSEL_SHIFT) /* DAC Channel2 */
# define COMP_CSR_INMSEL_PIN1 (6 << COMP_CSR_INMSEL_SHIFT) /* Input minus pin 1 */
# define COMP_CSR_INMSEL_PIN2 (7 << COMP_CSR_INMSEL_SHIFT) /* Input minus pin 2 */
# define COMP1_CSR_INMSEL_PB1 (6 << COMP_CSR_INMSEL_SHIFT) /* PB1 */
# define COMP1_CSR_INMSEL_PC4 (7 << COMP_CSR_INMSEL_SHIFT) /* PC4 */
# define COMP2_CSR_INMSEL_PB3 (6 << COMP_CSR_INMSEL_SHIFT) /* PB3 */
# define COMP2_CSR_INMSEL_PB7 (7 << COMP_CSR_INMSEL_SHIFT) /* PB7 */
#define COMP_CSR_INPSEL (1 << 7) /* Bit 7: Input plus selection bit */
#define COMP_CSR_INPSEL_MASK (1 << 7) /* Bit 7: Input plus selection bit */
# define COMP1_CSR_INPSEL_PIN1 (0)
# define COMP1_CSR_INPSEL_PIN2 COMP_CSR_INPSEL_MASK
# define COMP1_CSR_INPSEL_PC5 (0)
# define COMP1_CSR_INPSEL_PB2 COMP_CSR_INPSEL
# define COMP1_CSR_INPSEL_PB2 COMP_CSR_INPSEL_MASK
# define COMP2_CSR_INPSEL_PB4 (0)
# define COMP2_CSR_INPSEL_PB6 COMP_CSR_INPSEL
/* Bits 8-14: Reserved */
# define COMP2_CSR_INPSEL_PB6 COMP_CSR_INPSEL_MASK
#define COMP2_CSR_WINMODE (1 << 9) /* Bit 9: Windows mode selection bit (COMP2 only) */
# define COMP2_CSR_WINMODE_NOCONN (0) /* Comparator 2 input not connected to Comparator 1 */
# define COMP2_CSR_WINMODE_CONN COMP2_CSR_WINMODE /* Comparator 2 input connected to Comparator 1 */
#define COMP_CSR_POLARITY (1 << 15) /* Bit 15: Polarity selection bit */
#define COMP_CSR_POLARITY_MASK (1 << 15) /* Bit 15: Polarity selection bit */
# define COMP_CSR_POLARITY_NORMAL (0)
# define COMP_CSR_POLARITY_INVERT COMP_CSR_POLARITY
# define COMP_CSR_POLARITY_INVERT COMP_CSR_POLARITY_MASK
#define COMP_CSR_HYST_SHIFT (16) /* Bits 16-17: Hysteresis selection bits */
#define COMP_CSR_HYST_MASK (3 << COMP_CSR_HYST_SHIFT)
# define COMP_CSR_HYST_NONE (0 << COMP_CSR_HYST_SHIFT) /* No hysteresis */
# define COMP_CSR_HYST_LOW (1 << COMP_CSR_HYST_SHIFT) /* Low hysteresis */
# define COMP_CSR_HYST_MEDIUM (2 << COMP_CSR_HYST_SHIFT) /* Medium hysteresis */
# define COMP_CSR_HYST_HIGH (3 << COMP_CSR_HYST_SHIFT) /* High hysteresis */
#define COMP_CSR_BLANKING_SHIFT (18) /* Bits 18-20: Blanking source selection bits */
#define COMP_CSR_BLANKING_MASK (7 << COMP_CSR_BLANKING_SHIFT)
# define COMP_CSR_BLANKING_NONE (0 << COMP_CSR_BLANKING_SHIFT) /* No blanking */
# define COMP1_CSR_BLANKING_TIM1OC5 (1 << COMP_CSR_BLANKING_SHIFT) /* TIM1 OC5 is blanking source */
# define COMP1_CSR_BLANKING_TIM2OC3 (2 << COMP_CSR_BLANKING_SHIFT) /* TIM2 OC3 is blanking source */
# define COMP1_CSR_BLANKING_TIM3OC3 (4 << COMP_CSR_BLANKING_SHIFT) /* TIM3 OC3 is blanking source */
# define COMP2_CSR_BLANKING_TIM3OC4 (1 << COMP_CSR_BLANKING_SHIFT) /* TIM3 OC4 is blanking source */
# define COMP2_CSR_BLANKING_TIM8OC5 (2 << COMP_CSR_BLANKING_SHIFT) /* TIM8 OC5 is blanking source */
# define COMP2_CSR_BLANKING_TIM15OC1 (4 << COMP_CSR_BLANKING_SHIFT) /* TIM15 OC1 is blanking source */
#define COMP_CSR_BLANK_SHIFT (18) /* Bits 18-20: Blanking source selection bits */
#define COMP_CSR_BLANK_MASK (7 << COMP_CSR_BLANK_SHIFT)
# define COMP_CSR_BLANK_NONE (0 << COMP_CSR_BLANK_SHIFT) /* No blanking */
# define COMP1_CSR_BLANK_TIM1OC5 (1 << COMP_CSR_BLANK_SHIFT) /* TIM1 OC5 is blanking source */
# define COMP1_CSR_BLANK_TIM2OC3 (2 << COMP_CSR_BLANK_SHIFT) /* TIM2 OC3 is blanking source */
# define COMP1_CSR_BLANK_TIM3OC3 (4 << COMP_CSR_BLANK_SHIFT) /* TIM3 OC3 is blanking source */
# define COMP2_CSR_BLANK_TIM3OC4 (1 << COMP_CSR_BLANK_SHIFT) /* TIM3 OC4 is blanking source */
# define COMP2_CSR_BLANK_TIM8OC5 (2 << COMP_CSR_BLANK_SHIFT) /* TIM8 OC5 is blanking source */
# define COMP2_CSR_BLANK_TIM15OC1 (4 << COMP_CSR_BLANK_SHIFT) /* TIM15 OC1 is blanking source */
/* Bit 21: Reserved */
#define COMP_CSR_BRGEN (1 << 22) /* Bit 22: Scaler bridge enable */
#define COMP_CSR_SCALEN (1 << 23) /* Bit 23: Voltage scaler enable bit */
/* Bits 24-29: Reserved */
#define COMP_CSR_VALUE (1 << 30) /* Bit 30: Comparator output status bit */
#define COMP_CSR_LOCK (1 << 31) /* Bit 31: CSR register lock bit */
#define COMP_CSR_LOCK_MASK (1 << 31) /* Bit 31: CSR register lock bit */
# define COMP_CSR_LOCK_RW (0)
# define COMP_CSR_LOCK_RO COMP_CSR_LOCK
# define COMP_CSR_LOCK_RO COMP_CSR_LOCK_MASK
#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_COMP_H */

View File

@ -0,0 +1,316 @@
/************************************************************************************
* arch/arm/src/stm32l4/stm32l4_comp.c
*
* Copyright (c) 2017 Gregory Nutt. All rights reserved.
*
* Based on COMP driver from the Motorola MDK:
*
* Copyright (c) 2016 Motorola Mobility, LLC. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* Included Files
************************************************************************************/
#include "chip.h"
#include "stm32l4_comp.h"
#include "stm32l4_gpio.h"
#include "up_arch.h"
#include <errno.h>
#if !(defined(CONFIG_STM32L4_STM32L4X3) || defined(CONFIG_STM32L4_STM32L4X6))
# error "Unrecognized STM32 chip"
#endif
/************************************************************************************
* Private Functions
************************************************************************************/
/************************************************************************************
* Name: modify_csr
************************************************************************************/
static inline void modify_csr(int cmp, uint32_t clearbits, uint32_t setbits)
{
modifyreg32(cmp == STM32L4_COMP1 ? STM32L4_COMP1_CSR : STM32L4_COMP2_CSR,
clearbits, setbits);
}
/************************************************************************************
* Name: get_csr
************************************************************************************/
static inline uint32_t get_csr(int cmp)
{
return getreg32(cmp == STM32L4_COMP1 ? STM32L4_COMP1_CSR : STM32L4_COMP2_CSR);
}
/*************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: stm32l4_compconfig
*
* Description:
* Configure comparator and I/Os used as comparators inputs
*
* Parameters:
* cmp - comparator
* cfg - configuration
*
* Returns:
* 0 on success, a negated errno value on failure
*
************************************************************************************/
int stm32l4_compconfig(int cmp, const struct stm32l4_comp_config_s *cfg)
{
uint32_t regval = 0;
uint32_t mask = 0;
uint32_t clearbits;
uint32_t setbits;
/* Input plus */
mask |= COMP_CSR_INPSEL_MASK;
switch (cfg->inp)
{
case STM32L4_COMP_INP_PIN_1:
stm32l4_configgpio(cmp == STM32L4_COMP1 ? GPIO_COMP1_INP_1 : GPIO_COMP2_INP_1);
regval |= COMP1_CSR_INPSEL_PIN1;
break;
case STM32L4_COMP_INP_PIN_2:
stm32l4_configgpio(cmp == STM32L4_COMP1 ? GPIO_COMP1_INP_2 : GPIO_COMP2_INP_2);
regval |= COMP1_CSR_INPSEL_PIN2;
break;
#if defined(CONFIG_STM32L4_STM32L4X3)
case STM32L4_COMP_INP_PIN_3:
stm32l4_configgpio(cmp == STM32L4_COMP1 ? GPIO_COMP1_INP_3 : GPIO_COMP2_INP_3);
regval |= COMP1_CSR_INPSEL_PIN3;
break;
#endif
default:
return -EINVAL;
}
/* Input minus */
mask |= COMP_CSR_INMSEL_MASK;
switch (cfg->inm)
{
case STM32L4_COMP_INM_1_4_VREF:
regval |= COMP_CSR_INMSEL_25PCT;
mask |= (COMP_CSR_SCALEN | COMP_CSR_BRGEN);
regval |= (COMP_CSR_SCALEN | COMP_CSR_BRGEN);
break;
case STM32L4_COMP_INM_1_2_VREF:
regval |= COMP_CSR_INMSEL_50PCT;
mask |= (COMP_CSR_SCALEN | COMP_CSR_BRGEN);
regval |= (COMP_CSR_SCALEN | COMP_CSR_BRGEN);
break;
case STM32L4_COMP_INM_3_4_VREF:
regval |= COMP_CSR_INMSEL_75PCT;
mask |= (COMP_CSR_SCALEN | COMP_CSR_BRGEN);
regval |= (COMP_CSR_SCALEN | COMP_CSR_BRGEN);
break;
case STM32L4_COMP_INM_VREF:
regval |= COMP_CSR_INMSEL_VREF;
mask |= (COMP_CSR_SCALEN | COMP_CSR_BRGEN);
regval |= COMP_CSR_SCALEN;
break;
case STM32L4_COMP_INM_DAC_1:
regval |= COMP_CSR_INMSEL_DAC1;
break;
case STM32L4_COMP_INM_DAC_2:
regval |= COMP_CSR_INMSEL_DAC2;
break;
case STM32L4_COMP_INM_PIN_1:
stm32l4_configgpio(cmp == STM32L4_COMP1 ? GPIO_COMP1_INM_1 : GPIO_COMP2_INM_1);
regval |= COMP_CSR_INMSEL_PIN1;
break;
case STM32L4_COMP_INM_PIN_2:
stm32l4_configgpio(cmp == STM32L4_COMP1 ? GPIO_COMP1_INM_2 : GPIO_COMP2_INM_2);
#if defined(CONFIG_STM32L4_STM32L4X6)
regval |= COMP_CSR_INMSEL_PIN2;
#else
regval |= COMP_CSR_INMSEL_INMESEL;
mask |= COMP_CSR_INMESEL_MASK;
regval |= COMP_CSR_INMSEL_PIN2;
#endif
break;
#if defined(CONFIG_STM32L4_STM32L4X3)
case STM32L4_COMP_INM_PIN_3:
stm32l4_configgpio(cmp == STM32L4_COMP1 ? GPIO_COMP1_INM_3 : GPIO_COMP2_INM_3);
regval |= COMP_CSR_INMSEL_INMESEL;
mask |= COMP_CSR_INMESEL_MASK;
regval |= COMP_CSR_INMSEL_PIN3;
break;
case STM32L4_COMP_INM_PIN_4:
stm32l4_configgpio(cmp == STM32L4_COMP1 ? GPIO_COMP1_INM_4 : GPIO_COMP2_INM_4);
regval |= COMP_CSR_INMSEL_INMESEL;
mask |= COMP_CSR_INMESEL_MASK;
regval |= COMP_CSR_INMSEL_PIN4;
break;
case STM32L4_COMP_INM_PIN_5:
stm32l4_configgpio(cmp == STM32L4_COMP1 ? GPIO_COMP1_INM_5 : GPIO_COMP2_INM_5);
regval |= COMP_CSR_INMSEL_INMESEL;
mask |= COMP_CSR_INMESEL_MASK;
regval |= COMP_CSR_INMSEL_PIN5;
break;
#endif
default:
return -EINVAL;
}
/* Hysteresis */
mask |= COMP_CSR_HYST_MASK;
switch (cfg->hyst)
{
case STM32L4_COMP_HYST_NONE:
regval |= COMP_CSR_HYST_NONE;
break;
case STM32L4_COMP_HYST_LOW:
regval |= COMP_CSR_HYST_LOW;
break;
case STM32L4_COMP_HYST_MEDIUM:
regval |= COMP_CSR_HYST_MEDIUM;
break;
case STM32L4_COMP_HYST_HIGH:
regval |= COMP_CSR_HYST_HIGH;
break;
default:
return -EINVAL;
}
/* Power/speed Mode */
mask |= COMP_CSR_PWRMODE_MASK;
switch(cfg->speed)
{
case STM32L4_COMP_SPEED_HIGH:
regval |= COMP_CSR_PWRMODE_HIGH;
break;
case STM32L4_COMP_SPEED_MEDIUM:
regval |= COMP_CSR_PWRMODE_MEDIUM;
break;
case STM32L4_COMP_SPEED_LOW:
regval |= COMP_CSR_PWRMODE_LOW;
break;
default:
return -EINVAL;
}
/* Polarity */
mask |= COMP_CSR_POLARITY_MASK;
if (cfg->inverted)
{
regval |= COMP_CSR_POLARITY_INVERT;
}
/* Disable blanking */
mask |= COMP_CSR_BLANK_MASK;
regval |= COMP_CSR_BLANK_NONE;
clearbits = regval ^ mask;
setbits = regval;
modify_csr(cmp, clearbits, setbits);
return 0;
}
/************************************************************************************
* Name: stm32l4_compenable
*
* Description:
* Enable/disable comparator
*
* Parameters:
* cmp - comparator
* cfg - enable/disable flag
*
* Returns:
* 0 on success, a negated errno value on failure
*
************************************************************************************/
int stm32l4_compenable(int cmp, bool en)
{
uint32_t clearbits = en ? 0 : COMP_CSR_EN;
uint32_t setbits = en ? COMP_CSR_EN : 0;
modify_csr(cmp, clearbits, setbits);
return 0;
}
/************************************************************************************
* Name: stm32l4_compread
*
* Description:
* Read comparator output
*
* Parameters:
* - cmp: comparator
*
* Returns:
* true for high, false for low
*
************************************************************************************/
bool stm32l4_compread(int cmp)
{
return !!(get_csr(cmp) & COMP_CSR_VALUE);
}

View File

@ -0,0 +1,221 @@
/************************************************************************************
* arch/arm/src/stm32/stm32l4_comp.h
*
* Copyright (c) 2016 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_COMP_H
#define __ARCH_ARM_SRC_STM32L4_STM32L4_COMP_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include "chip/stm32l4_comp.h"
/************************************************************************************
* Public Types
************************************************************************************/
#if defined(CONFIG_STM32L4_STM32L4X3)
/* Comparators */
enum stm32l4_comp_e
{
STM32L4_COMP1,
STM32L4_COMP2,
STM32L4_COMP_NUM /* Number of comparators */
};
/* Plus input */
enum stm32l4_comp_inp_e
{
STM32L4_COMP_INP_PIN_1, /* COMP1: PC5, COMP2: PB4 */
STM32L4_COMP_INP_PIN_2, /* COMP1: PB2, COMP2: PB6 */
STM32L4_COMP_INP_PIN_3 /* COMP1: PA1, COMP2: PA3 */
};
/* Minus input */
enum stm32l4_comp_inm_e
{
STM32L4_COMP_INM_1_4_VREF,
STM32L4_COMP_INM_1_2_VREF,
STM32L4_COMP_INM_3_4_VREF,
STM32L4_COMP_INM_VREF,
STM32L4_COMP_INM_DAC_1,
STM32L4_COMP_INM_DAC_2,
STM32L4_COMP_INM_PIN_1, /* COMP1: PB1, COMP2: PB3 */
STM32L4_COMP_INM_PIN_2, /* COMP1: PC4, COMP2: PB7 */
STM32L4_COMP_INM_PIN_3, /* COMP1: PA0, COMP2: PA2 */
STM32L4_COMP_INM_PIN_4, /* COMP1: PA4, COMP2: PA4 */
STM32L4_COMP_INM_PIN_5 /* COMP1: PA5, COMP2: PA5 */
};
#elif defined(CONFIG_STM32L4_STM32L4X6)
/* Comparators */
enum stm32l4_comp_e
{
STM32L4_COMP1,
STM32L4_COMP2,
STM32L4_COMP_NUM /* Number of comparators */
};
/* Plus input */
enum stm32l4_comp_inp_e
{
STM32L4_COMP_INP_PIN_1, /* COMP1: PC5, COMP2: PB4 */
STM32L4_COMP_INP_PIN_2 /* COMP1: PB2, COMP2: PB6 */
};
/* Minus input */
enum stm32l4_comp_inm_e
{
STM32L4_COMP_INM_1_4_VREF,
STM32L4_COMP_INM_1_2_VREF,
STM32L4_COMP_INM_3_4_VREF,
STM32L4_COMP_INM_VREF,
STM32L4_COMP_INM_DAC_1,
STM32L4_COMP_INM_DAC_2,
STM32L4_COMP_INM_PIN_1, /* COMP1: PB1, COMP2: PB3 */
STM32L4_COMP_INM_PIN_2 /* COMP1: PC4, COMP2: PB7 */
};
#endif
/* Hysteresis */
enum stm32l4_comp_hyst_e
{
STM32L4_COMP_HYST_NONE,
STM32L4_COMP_HYST_LOW,
STM32L4_COMP_HYST_MEDIUM,
STM32L4_COMP_HYST_HIGH
};
/* Power/Speed Modes */
enum stm32l4_comp_speed_e
{
STM32L4_COMP_SPEED_HIGH,
STM32L4_COMP_SPEED_MEDIUM,
STM32L4_COMP_SPEED_LOW
};
/* Comparator configuration ***********************************************************/
struct stm32l4_comp_config_s
{
uint8_t inp; /* Plus input pin (see enum stm32l4_comp_inp_e) */
uint8_t inm; /* Minus input pin (see enum stm32l4_comp_inm_e) */
uint8_t hyst; /* Hysteresis (see enum stm32l4_comp_hyst_e) */
uint8_t speed; /* Speed (see stm32l4_comp_speed_e) */
bool inverted; /* Invert output? */
};
/************************************************************************************
* Public Function Prototypes
************************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/************************************************************************************
* Name: stm32l4_compconfig
*
* Description:
* Configure comparator and I/Os used as comparators inputs
*
* Parameters:
* cmp - comparator
* cfg - configuration
*
* Returns:
* 0 on success, a negated errno value on failure
*
************************************************************************************/
int stm32l4_compconfig(int cmp, const struct stm32l4_comp_config_s *cfg);
/************************************************************************************
* Name: stm32l4_compenable
*
* Description:
* Enable/disable comparator
*
* Parameters:
* cmp - comparator
* cfg - enable/disable flag
*
* Returns:
* 0 on success, a negated errno value on failure
*
************************************************************************************/
int stm32l4_compenable(int cmp, bool en);
/************************************************************************************
* Name: stm32l4_compread
*
* Description:
* Read comparator output
*
* Parameters:
* - cmp: comparator
*
* Returns:
* true for high, false for low
*
************************************************************************************/
bool stm32l4_compread(int cmp);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_COMP_H */

View File

@ -1,7 +1,7 @@
/************************************************************************************
* arch/arm/src/stm32l4/stm32l4_exti.h
*
* Copyright (C) 2009, 2012, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2009, 2012, 2015, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -110,6 +110,30 @@ xcpt_t stm32l4_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge,
xcpt_t stm32l4_exti_alarm(bool risingedge, bool fallingedge, bool event, xcpt_t func);
#endif
/****************************************************************************
* Name: stm32l4_exti_comp
*
* Description:
* Sets/clears comparator based events and interrupt triggers.
*
* Parameters:
* - cmp: comparator
* - rising/falling edge: enables interrupt on rising/falling edget
* - event: generate event when set
* - func: when non-NULL, generate interrupt
*
* Returns:
* The previous value of the interrupt handler function pointer. This
* value may, for example, be used to restore the previous handler when
* multiple handlers are used.
*
****************************************************************************/
#ifdef CONFIG_STM32L4_COMP
xcpt_t stm32l4_exti_comp(int cmp, bool risingedge, bool fallingedge,
bool event, xcpt_t func);
#endif
#undef EXTERN
#if defined(__cplusplus)
}

View File

@ -0,0 +1,172 @@
/****************************************************************************
* arch/arm/src/stm32/stm32l4_exti_comp.c
*
* Copyright (c) 2017 Gregory Nutt. All rights reserved
* Copyright (c) 2016 Motorola Mobility, LLC. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include "up_arch.h"
#include "stm32l4_comp.h"
#include "stm32l4_exti.h"
#include "chip/stm32l4_exti.h"
/****************************************************************************
* Private Data
****************************************************************************/
/* Interrupt handlers attached to the COMP EXTI lines */
static xcpt_t stm32l4_exti_comp_handlers[STM32L4_COMP_NUM];
/* Comparator EXTI lines */
static const uint32_t stm32l4_exti_comp_lines[STM32L4_COMP_NUM] =
{
#if defined(CONFIG_STM32L4_STM32L4X3) || defined (CONFIG_STM32L4_STM32L4X6)
EXTI1_COMP1,
EXTI1_COMP2
#else
# error "Unrecognized STM32L4 chip"
#endif
};
/****************************************************************************
* Private Functions
****************************************************************************/
static int stm32l4_exti_comp_isr(int irq, void *context)
{
uint32_t pr;
uint32_t ln;
int ret = 0;
int i;
/* Examine the state of each comparator line and dispatch interrupts */
pr = getreg32(STM32L4_EXTI1_PR);
for (i = 0; i < STM32L4_COMP_NUM; i++)
{
ln = stm32l4_exti_comp_lines[i];
if ((pr & ln) != 0)
{
/* Clear the pending interrupt */
putreg32(ln, STM32L4_EXTI1_PR);
if (stm32l4_exti_comp_handlers[i])
{
ret = stm32l4_exti_comp_handlers[i](irq, context);
}
}
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32l4_exti_comp
*
* Description:
* Sets/clears comparator based events and interrupt triggers.
*
* Parameters:
* - cmp: comparator
* - rising/falling edge: enables interrupt on rising/falling edget
* - event: generate event when set
* - func: when non-NULL, generate interrupt
*
* Returns:
* The previous value of the interrupt handler function pointer. This
* value may, for example, be used to restore the previous handler when
* multiple handlers are used.
*
****************************************************************************/
xcpt_t stm32l4_exti_comp(int cmp, bool risingedge, bool fallingedge,
bool event, xcpt_t func)
{
xcpt_t oldhandler;
irqstate_t flags;
uint32_t ln = stm32l4_exti_comp_lines[cmp];
/* Perform the following within a critical section so that the handler gets
* installed correctly before the next interrupt is received.
*/
flags = enter_critical_section();
/* Install external interrupt handlers */
if (func != NULL)
{
irq_attach(STM32L4_IRQ_COMP, stm32l4_exti_comp_isr);
up_enable_irq(STM32L4_IRQ_COMP);
}
else
{
up_disable_irq(STM32L4_IRQ_COMP);
}
/* Configure rising/falling edges */
modifyreg32(STM32L4_EXTI1_RTSR, risingedge ? 0 : ln, risingedge ? ln : 0);
modifyreg32(STM32L4_EXTI1_FTSR, fallingedge ? 0 : ln, fallingedge ? ln : 0);
/* Enable Events and Interrupts */
modifyreg32(STM32L4_EXTI1_EMR, event ? 0 : ln, event ? ln : 0);
modifyreg32(STM32L4_EXTI1_IMR, func ? 0 : ln, func ? ln : 0);
/* Get the previous IRQ handler and save the new IRQ handler. */
oldhandler = stm32l4_exti_comp_handlers[cmp];
stm32l4_exti_comp_handlers[cmp] = func;
/* Leave the critical section */
leave_critical_section(flags);
/* Return the old IRQ handler */
return oldhandler;
}