STM32L4 COMP: bind to upper half comp driver
This commit is contained in:
parent
cc0fea60ad
commit
6b1ccef2f9
@ -1221,6 +1221,7 @@ config STM32L4_TIM17
|
||||
config STM32L4_COMP
|
||||
bool "COMP"
|
||||
default n
|
||||
select COMP
|
||||
depends on STM32L4_HAVE_COMP
|
||||
|
||||
config STM32L4_SAI1
|
||||
|
@ -57,8 +57,8 @@
|
||||
|
||||
#include "chip.h"
|
||||
#include "stm32l4_adc.h"
|
||||
//#include "stm32l4_bkp.h"
|
||||
#include "stm32l4_can.h"
|
||||
#include "stm32l4_comp.h"
|
||||
#include "stm32l4_dbgmcu.h"
|
||||
#include "stm32l4_dma.h"
|
||||
#include "stm32l4_exti.h"
|
||||
|
@ -1,4 +1,5 @@
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
|
||||
* arch/arm/src/stm32l4/stm32l4_comp.c
|
||||
*
|
||||
* Copyright (c) 2017 Gregory Nutt. All rights reserved.
|
||||
@ -34,14 +35,22 @@
|
||||
* 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 <debug.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/analog/comp.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "stm32l4_comp.h"
|
||||
#include "stm32l4_exti.h"
|
||||
#include "stm32l4_gpio.h"
|
||||
#include "up_arch.h"
|
||||
|
||||
@ -52,54 +61,304 @@
|
||||
# error "Unrecognized STM32 chip"
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
#ifdef CONFIG_STM32L4_COMP
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* COMP Register access */
|
||||
|
||||
static inline void modify_csr(FAR const struct stm32l4_comp_config_s *cfg,
|
||||
uint32_t clearbits, uint32_t setbits);
|
||||
static inline uint32_t get_csr(const struct stm32l4_comp_config_s *cfg);
|
||||
static void stm32l4_compenable(FAR struct stm32l4_comp_config_s *cfg,
|
||||
bool en);
|
||||
static int stm32l4_compconfig(FAR const struct comp_dev_s *dev);
|
||||
|
||||
/* COMP Driver Methods */
|
||||
|
||||
static void comp_shutdown(FAR struct comp_dev_s *dev);
|
||||
static int comp_setup(FAR struct comp_dev_s *dev);
|
||||
static int comp_read(FAR struct comp_dev_s *dev);
|
||||
static int comp_ioctl(FAR struct comp_dev_s *dev, int cmd,
|
||||
unsigned long arg);
|
||||
static int comp_bind(FAR struct comp_dev_s *dev,
|
||||
FAR const struct comp_callback_s *callback);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct comp_ops_s g_compops =
|
||||
{
|
||||
.ao_shutdown = comp_shutdown,
|
||||
.ao_setup = comp_setup,
|
||||
.ao_read = comp_read,
|
||||
.ao_ioctl = comp_ioctl,
|
||||
.ao_bind = comp_bind,
|
||||
};
|
||||
|
||||
static struct stm32l4_comp_config_s g_comp1priv =
|
||||
{
|
||||
.interrupt =
|
||||
{
|
||||
.cb = NULL, /* will be bound to upper-half driver */
|
||||
.rising = true,
|
||||
.falling = false
|
||||
},
|
||||
.inp = STM32L4_COMP_INP_PIN_3,
|
||||
.inm = STM32L4_COMP_INM_VREF,
|
||||
.hyst = STM32L4_COMP_HYST_LOW,
|
||||
.speed = STM32L4_COMP_SPEED_MEDIUM,
|
||||
.inverted = false,
|
||||
.csr = STM32L4_COMP1_CSR,
|
||||
};
|
||||
|
||||
static struct comp_dev_s g_comp1dev =
|
||||
{
|
||||
.ad_ops = &g_compops,
|
||||
.ad_priv = &g_comp1priv,
|
||||
};
|
||||
|
||||
static struct stm32l4_comp_config_s g_comp2priv =
|
||||
{
|
||||
.interrupt =
|
||||
{
|
||||
.cb = NULL, /* will be bound to upper-half driver */
|
||||
.rising = true,
|
||||
.falling = false
|
||||
},
|
||||
.inp = STM32L4_COMP_INP_PIN_1,
|
||||
.inm = STM32L4_COMP_INM_DAC_1,
|
||||
.hyst = STM32L4_COMP_HYST_LOW,
|
||||
.speed = STM32L4_COMP_SPEED_MEDIUM,
|
||||
.inverted = false,
|
||||
.csr = STM32L4_COMP2_CSR,
|
||||
};
|
||||
|
||||
static struct comp_dev_s g_comp2dev =
|
||||
{
|
||||
.ad_ops = &g_compops,
|
||||
.ad_priv = &g_comp2priv,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: modify_csr
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void modify_csr(int cmp, uint32_t clearbits, uint32_t setbits)
|
||||
static inline void modify_csr(FAR const struct stm32l4_comp_config_s *cfg,
|
||||
uint32_t clearbits, uint32_t setbits)
|
||||
{
|
||||
modifyreg32(cmp == STM32L4_COMP1 ? STM32L4_COMP1_CSR : STM32L4_COMP2_CSR,
|
||||
clearbits, setbits);
|
||||
modifyreg32(cfg->csr, clearbits, setbits);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: get_csr
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t get_csr(int cmp)
|
||||
static inline uint32_t get_csr(const struct stm32l4_comp_config_s *cfg)
|
||||
{
|
||||
return getreg32(cmp == STM32L4_COMP1 ? STM32L4_COMP1_CSR : STM32L4_COMP2_CSR);
|
||||
return getreg32(cfg->csr);
|
||||
}
|
||||
|
||||
/*************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
/****************************************************************************
|
||||
* Name: comp_setup
|
||||
*
|
||||
* Description:
|
||||
* Configure the COMP. This method is called the first time that the COMP
|
||||
* device is opened. This will occur when the port is first opened.
|
||||
* This setup includes configuring and attaching COMP interrupts.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - pointer to device structure used by the driver
|
||||
*
|
||||
* Returned Value:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
static int comp_setup(FAR struct comp_dev_s *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Configure selected comparator */
|
||||
|
||||
ret = stm32l4_compconfig(dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
aerr("ERROR: Failed to initialize COMP: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: comp_shutdown
|
||||
*
|
||||
* Description:
|
||||
* Disable the COMP. This method is called when the COMP device is closed.
|
||||
* This method reverses the operation the setup method.
|
||||
* Works only if COMP device is not locked.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - pointer to device structure used by the driver
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void comp_shutdown(FAR struct comp_dev_s *dev)
|
||||
{
|
||||
FAR struct stm32l4_comp_config_s *cfg;
|
||||
|
||||
cfg = dev->ad_priv;
|
||||
stm32l4_compenable(cfg, false);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: comp_read
|
||||
*
|
||||
* Description:
|
||||
* Get the COMP output state.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - pointer to device structure used by the driver
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 if output is low (non-inverting input below inverting input),
|
||||
* 1 if output is high (non inverting input above inverting input).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int comp_read(FAR struct comp_dev_s *dev)
|
||||
{
|
||||
FAR struct stm32l4_comp_config_s *cfg;
|
||||
uint32_t regval;
|
||||
|
||||
cfg = dev->ad_priv;
|
||||
regval = get_csr(cfg);
|
||||
|
||||
return (((regval & COMP_CSR_VALUE) == 0) ? 0 : 1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: comp_ioctl
|
||||
*
|
||||
* Description:
|
||||
* All ioctl calls will be routed through this method.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - pointer to device structure used by the driver
|
||||
* cmd - command
|
||||
* arg - arguments passed with command
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int comp_ioctl(FAR struct comp_dev_s *dev, int cmd, unsigned long arg)
|
||||
{
|
||||
#warning "Missing logic"
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: comp_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind upper half callback.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - pointer to device structure used by the driver
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int comp_bind(FAR struct comp_dev_s *dev,
|
||||
FAR const struct comp_callback_s *callback)
|
||||
{
|
||||
FAR struct stm32l4_comp_config_s *priv =
|
||||
(FAR struct stm32l4_comp_config_s *)dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
priv->interrupt.cb = callback;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32l4_compenable
|
||||
*
|
||||
* Description:
|
||||
* Enable/disable comparator
|
||||
*
|
||||
* Parameters:
|
||||
* cmp - comparator
|
||||
* cfg - enable/disable flag
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void stm32l4_compenable(FAR struct stm32l4_comp_config_s *cfg, bool en)
|
||||
{
|
||||
uint32_t clearbits = en ? 0 : COMP_CSR_EN;
|
||||
uint32_t setbits = en ? COMP_CSR_EN : 0;
|
||||
|
||||
modify_csr(cfg, clearbits, setbits);
|
||||
}
|
||||
|
||||
static int stm32l4_exti_comp_isr(int irq, void *context, FAR void *arg)
|
||||
{
|
||||
FAR struct comp_dev_s *dev = (FAR struct comp_dev_s *)arg;
|
||||
struct stm32l4_comp_config_s *cfg = dev->ad_priv;
|
||||
|
||||
DEBUGASSERT(cfg->interrupt.cb &&
|
||||
(cfg->interrupt.rising || cfg->interrupt.falling));
|
||||
|
||||
ainfo("isr: %d\n", (cfg->csr == STM32L4_COMP1_CSR ? 0 : 1));
|
||||
|
||||
cfg->interrupt.cb->au_notify(dev, comp_read(dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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)
|
||||
static int stm32l4_compconfig(FAR const struct comp_dev_s *dev)
|
||||
{
|
||||
FAR struct stm32l4_comp_config_s *cfg;
|
||||
uint32_t regval = 0;
|
||||
uint32_t mask = 0;
|
||||
uint32_t clearbits;
|
||||
uint32_t setbits;
|
||||
int ret;
|
||||
int cmp;
|
||||
|
||||
cfg = dev->ad_priv;
|
||||
cmp = cfg->csr == STM32L4_COMP1_CSR ? STM32L4_COMP1 : STM32L4_COMP2;
|
||||
|
||||
/* Input plus */
|
||||
|
||||
@ -269,49 +528,76 @@ int stm32l4_compconfig(int cmp, const struct stm32l4_comp_config_s *cfg)
|
||||
clearbits = regval ^ mask;
|
||||
setbits = regval;
|
||||
|
||||
modify_csr(cmp, clearbits, setbits);
|
||||
modify_csr(cfg, clearbits, setbits);
|
||||
|
||||
/* Enable */
|
||||
|
||||
stm32l4_compenable(cfg, true);
|
||||
|
||||
/* Enable interrupt */
|
||||
|
||||
if (cfg->interrupt.cb && (cfg->interrupt.rising || cfg->interrupt.falling))
|
||||
{
|
||||
ret = stm32l4_exti_comp(cmp, cfg->interrupt.rising, cfg->interrupt.falling,
|
||||
0, stm32l4_exti_comp_isr, (void *)dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
aerr("stm32l4_exti_comp failed ret = %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ainfo("comp%d configured\n", cmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32l4_compenable
|
||||
/****************************************************************************
|
||||
* Name: stm32l4_compinitialize
|
||||
*
|
||||
* Description:
|
||||
* Enable/disable comparator
|
||||
* Initialize the COMP.
|
||||
*
|
||||
* Parameters:
|
||||
* cmp - comparator
|
||||
* cfg - enable/disable flag
|
||||
* Input Parameters:
|
||||
* intf - The COMP interface number.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, a negated errno value on failure
|
||||
* Returned Value:
|
||||
* Valid COMP device structure reference on success; a NULL on failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
* Assumptions:
|
||||
* 1. Clock to the COMP block has enabled,
|
||||
* 2. Board-specific logic has already configured
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stm32l4_compenable(int cmp, bool en)
|
||||
FAR struct comp_dev_s* stm32l4_compinitialize(int intf,
|
||||
FAR const struct stm32l4_comp_config_s *cfg)
|
||||
{
|
||||
uint32_t clearbits = en ? 0 : COMP_CSR_EN;
|
||||
uint32_t setbits = en ? COMP_CSR_EN : 0;
|
||||
FAR struct comp_dev_s *dev;
|
||||
|
||||
modify_csr(cmp, clearbits, setbits);
|
||||
return 0;
|
||||
switch (intf)
|
||||
{
|
||||
case 1:
|
||||
ainfo("COMP1 selected\n");
|
||||
dev = &g_comp1dev;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ainfo("COMP2 selected\n");
|
||||
dev = &g_comp2dev;
|
||||
break;
|
||||
|
||||
default:
|
||||
aerr("ERROR: No COMP interface defined\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cfg)
|
||||
{
|
||||
memcpy(dev->ad_priv, cfg, sizeof(*cfg));
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
#endif /* CONFIG_STM32L4_COMP */
|
||||
|
@ -51,6 +51,7 @@
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_STM32L4_STM32L4X3)
|
||||
|
||||
/* Comparators */
|
||||
|
||||
enum stm32l4_comp_e
|
||||
@ -142,11 +143,19 @@ enum stm32l4_comp_speed_e
|
||||
|
||||
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? */
|
||||
struct
|
||||
{
|
||||
FAR const struct comp_callback_s *cb;
|
||||
bool rising;
|
||||
bool falling;
|
||||
} interrupt;
|
||||
|
||||
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? */
|
||||
uint32_t csr; /* Control and status register */
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
@ -162,55 +171,27 @@ extern "C"
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32l4_compconfig
|
||||
/****************************************************************************
|
||||
* Name: stm32l4_compinitialize
|
||||
*
|
||||
* Description:
|
||||
* Configure comparator and I/Os used as comparators inputs
|
||||
* Initialize the COMP.
|
||||
*
|
||||
* Parameters:
|
||||
* cmp - comparator
|
||||
* cfg - configuration
|
||||
* Input Parameters:
|
||||
* intf - The COMP interface number.
|
||||
* cfg - configuration
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, a negated errno value on failure
|
||||
* Returned Value:
|
||||
* Valid COMP device structure reference on success; a NULL on failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
* Assumptions:
|
||||
* 1. Clock to the COMP block has enabled,
|
||||
* 2. Board-specific logic has already configured
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
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);
|
||||
FAR struct comp_dev_s* stm32l4_compinitialize(int intf,
|
||||
FAR const struct stm32l4_comp_config_s *cfg);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
@ -159,23 +159,23 @@ int stm32l4_exti_comp(int cmp, bool risingedge, bool fallingedge,
|
||||
up_disable_irq(STM32L4_IRQ_COMP);
|
||||
}
|
||||
|
||||
/* Configure rising/falling edges */
|
||||
/* Configure rising/falling edges */
|
||||
|
||||
modifyreg32(STM32L4_EXTI1_RTSR, risingedge ? 0 : ln, risingedge ? ln : 0);
|
||||
modifyreg32(STM32L4_EXTI1_FTSR, fallingedge ? 0 : ln, fallingedge ? ln : 0);
|
||||
modifyreg32(STM32L4_EXTI1_RTSR, risingedge ? 0 : ln, risingedge ? ln : 0);
|
||||
modifyreg32(STM32L4_EXTI1_FTSR, fallingedge ? 0 : ln, fallingedge ? ln : 0);
|
||||
|
||||
/* Enable Events and Interrupts */
|
||||
/* Enable Events and Interrupts */
|
||||
|
||||
modifyreg32(STM32L4_EXTI1_EMR, event ? 0 : ln, event ? ln : 0);
|
||||
modifyreg32(STM32L4_EXTI1_IMR, func ? 0 : ln, func ? ln : 0);
|
||||
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. */
|
||||
/* Get the previous IRQ handler and save the new IRQ handler. */
|
||||
|
||||
g_comp_handlers[cmp].callback = func;
|
||||
g_comp_handlers[cmp].arg = arg;
|
||||
g_comp_handlers[cmp].callback = func;
|
||||
g_comp_handlers[cmp].arg = arg;
|
||||
|
||||
/* Leave the critical section */
|
||||
/* Leave the critical section */
|
||||
|
||||
leave_critical_section(flags);
|
||||
return OK;
|
||||
leave_critical_section(flags);
|
||||
return OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user