zephyr/drivers/comparator/comparator_nrf_comp.c

765 lines
17 KiB
C

/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <nrfx_comp.h>
#include <zephyr/drivers/comparator/nrf_comp.h>
#include <zephyr/kernel.h>
#include <zephyr/pm/device.h>
#define DT_DRV_COMPAT nordic_nrf_comp
#define SHIM_NRF_COMP_DT_INST_REFSEL(inst) \
_CONCAT(COMP_NRF_COMP_REFSEL_, DT_INST_STRING_TOKEN(inst, refsel))
#define SHIM_NRF_COMP_DT_INST_REFSEL_IS_AREF(inst) \
DT_INST_ENUM_HAS_VALUE(inst, refsel, AREF)
#define SHIM_NRF_COMP_DT_INST_EXTREFSEL(inst) \
_CONCAT(COMP_NRF_COMP_EXTREFSEL_, DT_INST_STRING_TOKEN(inst, extrefsel))
#define SHIM_NRF_COMP_DT_INST_MAIN_MODE_IS_SE(inst) \
DT_INST_ENUM_HAS_VALUE(inst, main_mode, SE)
#define SHIM_NRF_COMP_DT_INST_MAIN_MODE_IS_DIFF(inst) \
DT_INST_ENUM_HAS_VALUE(inst, main_mode, DIFF)
#define SHIM_NRF_COMP_DT_INST_TH_DOWN(inst) \
DT_INST_PROP(inst, th_down)
#define SHIM_NRF_COMP_DT_INST_TH_UP(inst) \
DT_INST_PROP(inst, th_up)
#define SHIM_NRF_COMP_DT_INST_SP_MODE(inst) \
_CONCAT(COMP_NRF_COMP_SP_MODE_, DT_INST_STRING_TOKEN(inst, sp_mode))
#define SHIM_NRF_COMP_DT_INST_ENABLE_HYST(inst) \
DT_INST_PROP(inst, enable_hyst)
#define SHIM_NRF_COMP_DT_INST_ISOURCE(inst) \
_CONCAT(COMP_NRF_COMP_ISOURCE_, DT_INST_STRING_TOKEN(inst, isource))
#define SHIM_NRF_COMP_DT_INST_PSEL(inst) \
_CONCAT(COMP_NRF_COMP_PSEL_, DT_INST_STRING_TOKEN(inst, psel))
#if defined(COMP_HYST_HYST_Hyst40mV)
#define NRF_COMP_HYST_ENABLED NRF_COMP_HYST_40MV
#elif defined(COMP_HYST_HYST_Hyst50mV)
#define NRF_COMP_HYST_ENABLED NRF_COMP_HYST_50MV
#endif
#define NRF_COMP_HYST_DISABLED NRF_COMP_HYST_NO_HYST
#if defined(NRF_COMP_HYST_ENABLED)
#define NRF_COMP_HAS_HYST 1
#else
#define NRF_COMP_HAS_HYST 0
#endif
struct shim_nrf_comp_data {
uint32_t event_mask;
bool started;
atomic_t triggered;
comparator_callback_t callback;
void *user_data;
};
#if (NRF_COMP_HAS_AIN_AS_PIN)
static const uint32_t shim_nrf_comp_ain_map[] = {
#if defined(CONFIG_SOC_NRF54H20) || defined(CONFIG_SOC_NRF9280)
NRF_PIN_PORT_TO_PIN_NUMBER(0U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(1U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(2U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(3U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(4U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(5U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(6U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(7U, 1),
#elif defined(CONFIG_SOC_NRF54L15)
NRF_PIN_PORT_TO_PIN_NUMBER(4U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(5U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(6U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(7U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(11U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(12U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(13U, 1),
NRF_PIN_PORT_TO_PIN_NUMBER(14U, 1),
#endif
};
#endif
#if SHIM_NRF_COMP_DT_INST_MAIN_MODE_IS_SE(0)
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_TH_DOWN(0) < 64);
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_TH_UP(0) < 64);
#endif
#if NRF_COMP_HAS_AIN_AS_PIN
BUILD_ASSERT((COMP_NRF_COMP_PSEL_AIN0 == 0));
BUILD_ASSERT((COMP_NRF_COMP_PSEL_AIN7 == 7));
BUILD_ASSERT((COMP_NRF_COMP_EXTREFSEL_AIN0 == 0));
BUILD_ASSERT((COMP_NRF_COMP_EXTREFSEL_AIN7 == 7));
#else
#ifndef COMP_PSEL_PSEL_AnalogInput4
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_PSEL(0) != COMP_NRF_COMP_PSEL_AIN4);
#endif
#ifndef COMP_PSEL_PSEL_AnalogInput5
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_PSEL(0) != COMP_NRF_COMP_PSEL_AIN5);
#endif
#ifndef COMP_PSEL_PSEL_AnalogInput6
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_PSEL(0) != COMP_NRF_COMP_PSEL_AIN6);
#endif
#ifndef COMP_PSEL_PSEL_AnalogInput7
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_PSEL(0) != COMP_NRF_COMP_PSEL_AIN7);
#endif
#endif
#ifndef COMP_PSEL_PSEL_VddDiv2
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_PSEL(0) != COMP_NRF_COMP_PSEL_VDD_DIV2);
#endif
#ifndef COMP_PSEL_PSEL_VddhDiv5
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_PSEL(0) != COMP_NRF_COMP_PSEL_VDDH_DIV5);
#endif
#ifndef COMP_MODE_SP_Normal
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_SP_MODE(0) != COMP_NRF_COMP_SP_MODE_NORMAL);
#endif
#if NRF_COMP_HAS_ISOURCE
#ifndef COMP_ISOURCE_ISOURCE_Ien2uA5
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_ISOURCE(0) != COMP_NRF_COMP_ISOURCE_2UA5);
#endif
#ifndef COMP_ISOURCE_ISOURCE_Ien5uA
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_ISOURCE(0) != COMP_NRF_COMP_ISOURCE_5UA);
#endif
#ifndef COMP_ISOURCE_ISOURCE_Ien10uA
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_ISOURCE(0) != COMP_NRF_COMP_ISOURCE_10UA);
#endif
#endif
#if SHIM_NRF_COMP_DT_INST_REFSEL_IS_AREF(0)
#ifndef COMP_EXTREFSEL_EXTREFSEL_AnalogReference4
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_EXTREFSEL(0) != COMP_NRF_COMP_EXTREFSEL_AIN4);
#endif
#ifndef COMP_EXTREFSEL_EXTREFSEL_AnalogReference5
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_EXTREFSEL(0) != COMP_NRF_COMP_EXTREFSEL_AIN5);
#endif
#ifndef COMP_EXTREFSEL_EXTREFSEL_AnalogReference6
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_EXTREFSEL(0) != COMP_NRF_COMP_EXTREFSEL_AIN6);
#endif
#ifndef COMP_EXTREFSEL_EXTREFSEL_AnalogReference7
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_EXTREFSEL(0) != COMP_NRF_COMP_EXTREFSEL_AIN7);
#endif
#endif
#if SHIM_NRF_COMP_DT_INST_MAIN_MODE_IS_SE(0)
#ifndef COMP_REFSEL_REFSEL_Int1V8
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_REFSEL(0) != COMP_NRF_COMP_REFSEL_INT_1V8);
#endif
#ifndef COMP_REFSEL_REFSEL_Int2V4
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_REFSEL(0) != COMP_NRF_COMP_REFSEL_INT_2V4);
#endif
#ifndef COMP_REFSEL_REFSEL_AVDDAO1V8
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_REFSEL(0) != COMP_NRF_COMP_REFSEL_AVDDAO1V8);
#endif
#ifndef COMP_REFSEL_REFSEL_VDD
BUILD_ASSERT(SHIM_NRF_COMP_DT_INST_REFSEL(0) != COMP_NRF_COMP_REFSEL_VDD);
#endif
#endif
#if SHIM_NRF_COMP_DT_INST_MAIN_MODE_IS_DIFF(0)
#if SHIM_NRF_COMP_DT_INST_ENABLE_HYST(0)
BUILD_ASSERT(NRF_COMP_HAS_HYST);
#endif
#endif
#if SHIM_NRF_COMP_DT_INST_MAIN_MODE_IS_SE(0)
static const struct comp_nrf_comp_se_config shim_nrf_comp_config0 = {
.psel = SHIM_NRF_COMP_DT_INST_PSEL(0),
.sp_mode = SHIM_NRF_COMP_DT_INST_SP_MODE(0),
.isource = SHIM_NRF_COMP_DT_INST_ISOURCE(0),
#if SHIM_NRF_COMP_DT_INST_REFSEL_IS_AREF(0)
.extrefsel = SHIM_NRF_COMP_DT_INST_EXTREFSEL(0),
#endif
.refsel = SHIM_NRF_COMP_DT_INST_REFSEL(0),
.th_down = SHIM_NRF_COMP_DT_INST_TH_DOWN(0),
.th_up = SHIM_NRF_COMP_DT_INST_TH_UP(0),
};
#else
static const struct comp_nrf_comp_diff_config shim_nrf_comp_config0 = {
.psel = SHIM_NRF_COMP_DT_INST_PSEL(0),
.sp_mode = SHIM_NRF_COMP_DT_INST_SP_MODE(0),
.isource = SHIM_NRF_COMP_DT_INST_ISOURCE(0),
.extrefsel = SHIM_NRF_COMP_DT_INST_EXTREFSEL(0),
.enable_hyst = SHIM_NRF_COMP_DT_INST_ENABLE_HYST(0),
};
#endif
static struct shim_nrf_comp_data shim_nrf_comp_data0;
#if CONFIG_PM_DEVICE
static bool shim_nrf_comp_is_resumed(void)
{
enum pm_device_state state;
(void)pm_device_state_get(DEVICE_DT_INST_GET(0), &state);
return state == PM_DEVICE_STATE_ACTIVE;
}
#else
static bool shim_nrf_comp_is_resumed(void)
{
return true;
}
#endif
static void shim_nrf_comp_start(void)
{
if (shim_nrf_comp_data0.started) {
return;
}
nrfx_comp_start(shim_nrf_comp_data0.event_mask, 0);
shim_nrf_comp_data0.started = true;
}
static void shim_nrf_comp_stop(void)
{
if (!shim_nrf_comp_data0.started) {
return;
}
nrfx_comp_stop();
shim_nrf_comp_data0.started = false;
}
static int shim_nrf_comp_pm_callback(const struct device *dev, enum pm_device_action action)
{
ARG_UNUSED(dev);
switch (action) {
case PM_DEVICE_ACTION_RESUME:
shim_nrf_comp_start();
break;
#if CONFIG_PM_DEVICE
case PM_DEVICE_ACTION_SUSPEND:
shim_nrf_comp_stop();
break;
#endif
default:
return -ENOTSUP;
}
return 0;
}
#if (NRF_COMP_HAS_AIN_AS_PIN)
static int shim_nrf_comp_psel_to_nrf(enum comp_nrf_comp_psel shim,
nrf_comp_input_t *nrf)
{
if (shim >= ARRAY_SIZE(shim_nrf_comp_ain_map)) {
return -EINVAL;
}
*nrf = shim_nrf_comp_ain_map[(uint32_t)shim];
return 0;
}
#else
static int shim_nrf_comp_psel_to_nrf(enum comp_nrf_comp_psel shim,
nrf_comp_input_t *nrf)
{
switch (shim) {
case COMP_NRF_COMP_PSEL_AIN0:
*nrf = NRF_COMP_INPUT_0;
break;
case COMP_NRF_COMP_PSEL_AIN1:
*nrf = NRF_COMP_INPUT_1;
break;
case COMP_NRF_COMP_PSEL_AIN2:
*nrf = NRF_COMP_INPUT_2;
break;
case COMP_NRF_COMP_PSEL_AIN3:
*nrf = NRF_COMP_INPUT_3;
break;
#if defined(COMP_PSEL_PSEL_AnalogInput4)
case COMP_NRF_COMP_PSEL_AIN4:
*nrf = NRF_COMP_INPUT_4;
break;
#endif
#if defined(COMP_PSEL_PSEL_AnalogInput5)
case COMP_NRF_COMP_PSEL_AIN5:
*nrf = NRF_COMP_INPUT_5;
break;
#endif
#if defined(COMP_PSEL_PSEL_AnalogInput6)
case COMP_NRF_COMP_PSEL_AIN6:
*nrf = NRF_COMP_INPUT_6;
break;
#endif
#if defined(COMP_PSEL_PSEL_AnalogInput7)
case COMP_NRF_COMP_PSEL_AIN7:
*nrf = NRF_COMP_INPUT_7;
break;
#endif
#if defined(COMP_PSEL_PSEL_VddDiv2)
case COMP_NRF_COMP_PSEL_VDD_DIV2:
*nrf = NRF_COMP_VDD_DIV2;
break;
#endif
#if defined(COMP_PSEL_PSEL_VddhDiv5)
case COMP_NRF_COMP_PSEL_VDDH_DIV5:
*nrf = NRF_COMP_VDDH_DIV5;
break;
#endif
default:
return -EINVAL;
}
return 0;
}
#endif
static int shim_nrf_comp_sp_mode_to_nrf(enum comp_nrf_comp_sp_mode shim,
nrf_comp_sp_mode_t *nrf)
{
switch (shim) {
case COMP_NRF_COMP_SP_MODE_LOW:
*nrf = NRF_COMP_SP_MODE_LOW;
break;
#if defined(COMP_MODE_SP_Normal)
case COMP_NRF_COMP_SP_MODE_NORMAL:
*nrf = NRF_COMP_SP_MODE_NORMAL;
break;
#endif
case COMP_NRF_COMP_SP_MODE_HIGH:
*nrf = NRF_COMP_SP_MODE_HIGH;
break;
default:
return -EINVAL;
}
return 0;
}
#if NRF_COMP_HAS_ISOURCE
static int shim_nrf_comp_isource_to_nrf(enum comp_nrf_comp_isource shim,
nrf_isource_t *nrf)
{
switch (shim) {
case COMP_NRF_COMP_ISOURCE_DISABLED:
*nrf = NRF_COMP_ISOURCE_OFF;
break;
#if defined(COMP_ISOURCE_ISOURCE_Ien2uA5)
case COMP_NRF_COMP_ISOURCE_2UA5:
*nrf = NRF_COMP_ISOURCE_IEN_2UA5;
break;
#endif
#if defined(COMP_ISOURCE_ISOURCE_Ien5uA)
case COMP_NRF_COMP_ISOURCE_5UA:
*nrf = NRF_COMP_ISOURCE_IEN_5UA;
break;
#endif
#if defined(COMP_ISOURCE_ISOURCE_Ien10uA)
case COMP_NRF_COMP_ISOURCE_10UA:
*nrf = NRF_COMP_ISOURCE_IEN_10UA;
break;
#endif
default:
return -EINVAL;
}
return 0;
}
#endif
#if (NRF_COMP_HAS_AIN_AS_PIN)
static int shim_nrf_comp_extrefsel_to_nrf(enum comp_nrf_comp_extrefsel shim,
nrf_comp_ext_ref_t *nrf)
{
if (shim >= ARRAY_SIZE(shim_nrf_comp_ain_map)) {
return -EINVAL;
}
*nrf = shim_nrf_comp_ain_map[(uint32_t)shim];
return 0;
}
#else
static int shim_nrf_comp_extrefsel_to_nrf(enum comp_nrf_comp_extrefsel shim,
nrf_comp_ext_ref_t *nrf)
{
switch (shim) {
case COMP_NRF_COMP_EXTREFSEL_AIN0:
*nrf = NRF_COMP_EXT_REF_0;
break;
case COMP_NRF_COMP_EXTREFSEL_AIN1:
*nrf = NRF_COMP_EXT_REF_1;
break;
case COMP_NRF_COMP_EXTREFSEL_AIN2:
*nrf = NRF_COMP_EXT_REF_2;
break;
case COMP_NRF_COMP_EXTREFSEL_AIN3:
*nrf = NRF_COMP_EXT_REF_3;
break;
#if defined(COMP_EXTREFSEL_EXTREFSEL_AnalogReference4)
case COMP_NRF_COMP_EXTREFSEL_AIN4:
*nrf = NRF_COMP_EXT_REF_4;
break;
#endif
#if defined(COMP_EXTREFSEL_EXTREFSEL_AnalogReference5)
case COMP_NRF_COMP_EXTREFSEL_AIN5:
*nrf = NRF_COMP_EXT_REF_5;
break;
#endif
#if defined(COMP_EXTREFSEL_EXTREFSEL_AnalogReference6)
case COMP_NRF_COMP_EXTREFSEL_AIN6:
*nrf = NRF_COMP_EXT_REF_6;
break;
#endif
#if defined(COMP_EXTREFSEL_EXTREFSEL_AnalogReference7)
case COMP_NRF_COMP_EXTREFSEL_AIN7:
*nrf = NRF_COMP_EXT_REF_7;
break;
#endif
default:
return -EINVAL;
}
return 0;
}
#endif
static int shim_nrf_comp_refsel_to_nrf(enum comp_nrf_comp_refsel shim,
nrf_comp_ref_t *nrf)
{
switch (shim) {
case COMP_NRF_COMP_REFSEL_INT_1V2:
*nrf = NRF_COMP_REF_INT_1V2;
break;
#if defined(COMP_REFSEL_REFSEL_Int1V8)
case COMP_NRF_COMP_REFSEL_INT_1V8:
*nrf = NRF_COMP_REF_INT_1V8;
break;
#endif
#if defined(COMP_REFSEL_REFSEL_Int2V4)
case COMP_NRF_COMP_REFSEL_INT_2V4:
*nrf = NRF_COMP_REF_INT_2V4;
break;
#endif
#if defined(COMP_REFSEL_REFSEL_AVDDAO1V8)
case COMP_NRF_COMP_REFSEL_AVDDAO1V8:
*nrf = NRF_COMP_REF_AVDDAO1V8;
break;
#endif
#if defined(COMP_REFSEL_REFSEL_VDD)
case COMP_NRF_COMP_REFSEL_VDD:
*nrf = NRF_COMP_REF_VDD;
break;
#endif
case COMP_NRF_COMP_REFSEL_AREF:
*nrf = NRF_COMP_REF_AREF;
break;
default:
return -EINVAL;
}
return 0;
}
static int shim_nrf_comp_se_config_to_nrf(const struct comp_nrf_comp_se_config *shim,
nrfx_comp_config_t *nrf)
{
if (shim_nrf_comp_refsel_to_nrf(shim->refsel, &nrf->reference)) {
return -EINVAL;
}
if (shim_nrf_comp_extrefsel_to_nrf(shim->extrefsel, &nrf->ext_ref)) {
return -EINVAL;
}
nrf->main_mode = NRF_COMP_MAIN_MODE_SE;
if (shim->th_down > 63 || shim->th_up > 63) {
return -EINVAL;
}
nrf->threshold.th_down = shim->th_down;
nrf->threshold.th_up = shim->th_up;
if (shim_nrf_comp_sp_mode_to_nrf(shim->sp_mode, &nrf->speed_mode)) {
return -EINVAL;
}
nrf->hyst = NRF_COMP_HYST_NO_HYST;
#if NRF_COMP_HAS_ISOURCE
if (shim_nrf_comp_isource_to_nrf(shim->isource, &nrf->isource)) {
return -EINVAL;
}
#else
if (shim->isource != COMP_NRF_COMP_ISOURCE_DISABLED) {
return -EINVAL;
}
#endif
if (shim_nrf_comp_psel_to_nrf(shim->psel, &nrf->input)) {
return -EINVAL;
}
nrf->interrupt_priority = 0;
return 0;
}
static int shim_nrf_comp_diff_config_to_nrf(const struct comp_nrf_comp_diff_config *shim,
nrfx_comp_config_t *nrf)
{
nrf->reference = NRF_COMP_REF_AREF;
if (shim_nrf_comp_extrefsel_to_nrf(shim->extrefsel, &nrf->ext_ref)) {
return -EINVAL;
}
nrf->main_mode = NRF_COMP_MAIN_MODE_DIFF;
nrf->threshold.th_down = 0;
nrf->threshold.th_up = 0;
if (shim_nrf_comp_sp_mode_to_nrf(shim->sp_mode, &nrf->speed_mode)) {
return -EINVAL;
}
#if NRF_COMP_HAS_HYST
if (shim->enable_hyst) {
nrf->hyst = NRF_COMP_HYST_ENABLED;
} else {
nrf->hyst = NRF_COMP_HYST_DISABLED;
}
#else
if (shim->enable_hyst) {
return -EINVAL;
}
#endif
#if NRF_COMP_HAS_ISOURCE
if (shim_nrf_comp_isource_to_nrf(shim->isource, &nrf->isource)) {
return -EINVAL;
}
#else
if (shim->isource != COMP_NRF_COMP_ISOURCE_DISABLED) {
return -EINVAL;
}
#endif
if (shim_nrf_comp_psel_to_nrf(shim->psel, &nrf->input)) {
return -EINVAL;
}
nrf->interrupt_priority = 0;
return 0;
}
static int shim_nrf_comp_get_output(const struct device *dev)
{
ARG_UNUSED(dev);
return nrfx_comp_sample();
}
static int shim_nrf_comp_set_trigger(const struct device *dev,
enum comparator_trigger trigger)
{
shim_nrf_comp_stop();
switch (trigger) {
case COMPARATOR_TRIGGER_NONE:
shim_nrf_comp_data0.event_mask = 0;
break;
case COMPARATOR_TRIGGER_RISING_EDGE:
shim_nrf_comp_data0.event_mask = NRF_COMP_INT_UP_MASK;
break;
case COMPARATOR_TRIGGER_FALLING_EDGE:
shim_nrf_comp_data0.event_mask = NRF_COMP_INT_DOWN_MASK;
break;
case COMPARATOR_TRIGGER_BOTH_EDGES:
shim_nrf_comp_data0.event_mask = NRF_COMP_INT_CROSS_MASK;
break;
}
if (shim_nrf_comp_is_resumed()) {
shim_nrf_comp_start();
}
return 0;
}
static int shim_nrf_comp_set_trigger_callback(const struct device *dev,
comparator_callback_t callback,
void *user_data)
{
shim_nrf_comp_stop();
shim_nrf_comp_data0.callback = callback;
shim_nrf_comp_data0.user_data = user_data;
if (callback != NULL && atomic_test_and_clear_bit(&shim_nrf_comp_data0.triggered, 0)) {
callback(dev, user_data);
}
if (shim_nrf_comp_is_resumed()) {
shim_nrf_comp_start();
}
return 0;
}
static int shim_nrf_comp_trigger_is_pending(const struct device *dev)
{
ARG_UNUSED(dev);
return atomic_test_and_clear_bit(&shim_nrf_comp_data0.triggered, 0);
}
static const struct comparator_driver_api shim_nrf_comp_api = {
.get_output = shim_nrf_comp_get_output,
.set_trigger = shim_nrf_comp_set_trigger,
.set_trigger_callback = shim_nrf_comp_set_trigger_callback,
.trigger_is_pending = shim_nrf_comp_trigger_is_pending,
};
static int shim_nrf_comp_reconfigure(const nrfx_comp_config_t *nrf)
{
shim_nrf_comp_stop();
(void)nrfx_comp_reconfigure(nrf);
if (shim_nrf_comp_is_resumed()) {
shim_nrf_comp_start();
}
return 0;
}
int comp_nrf_comp_configure_se(const struct device *dev,
const struct comp_nrf_comp_se_config *config)
{
nrfx_comp_config_t nrf = {};
ARG_UNUSED(dev);
if (shim_nrf_comp_se_config_to_nrf(config, &nrf)) {
return -EINVAL;
}
return shim_nrf_comp_reconfigure(&nrf);
}
int comp_nrf_comp_configure_diff(const struct device *dev,
const struct comp_nrf_comp_diff_config *config)
{
nrfx_comp_config_t nrf = {};
ARG_UNUSED(dev);
if (shim_nrf_comp_diff_config_to_nrf(config, &nrf)) {
return -EINVAL;
}
return shim_nrf_comp_reconfigure(&nrf);
}
static void shim_nrf_comp_event_handler(nrf_comp_event_t event)
{
ARG_UNUSED(event);
if (shim_nrf_comp_data0.callback == NULL) {
atomic_set_bit(&shim_nrf_comp_data0.triggered, 0);
return;
}
shim_nrf_comp_data0.callback(DEVICE_DT_INST_GET(0), shim_nrf_comp_data0.user_data);
atomic_clear_bit(&shim_nrf_comp_data0.triggered, 0);
}
static int shim_nrf_comp_init(const struct device *dev)
{
nrfx_comp_config_t nrf = {};
IRQ_CONNECT(DT_INST_IRQN(0),
DT_INST_IRQ(0, priority),
nrfx_isr,
nrfx_comp_irq_handler,
0);
irq_enable(DT_INST_IRQN(0));
#if SHIM_NRF_COMP_DT_INST_MAIN_MODE_IS_SE(0)
(void)shim_nrf_comp_se_config_to_nrf(&shim_nrf_comp_config0, &nrf);
#else
(void)shim_nrf_comp_diff_config_to_nrf(&shim_nrf_comp_config0, &nrf);
#endif
if (nrfx_comp_init(&nrf, shim_nrf_comp_event_handler) != NRFX_SUCCESS) {
return -ENODEV;
}
return pm_device_driver_init(dev, shim_nrf_comp_pm_callback);
}
PM_DEVICE_DT_INST_DEFINE(0, shim_nrf_comp_pm_callback);
DEVICE_DT_INST_DEFINE(0,
shim_nrf_comp_init,
PM_DEVICE_DT_INST_GET(0),
NULL,
NULL,
POST_KERNEL,
CONFIG_COMPARATOR_INIT_PRIORITY,
&shim_nrf_comp_api);