From 20b565a9f38bb6be0faaa216fe9b70f631da8705 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Sun, 16 Feb 2020 13:58:28 +0100 Subject: [PATCH] drivers: dac: add driver for the NXP Kinetis DAC32 Add driver shim for the NXP Kinetis Digital-to-Analog (DAC32) module. Signed-off-by: Henrik Brix Andersen --- drivers/dac/CMakeLists.txt | 1 + drivers/dac/Kconfig | 2 + drivers/dac/Kconfig.mcux | 11 ++++ drivers/dac/dac_mcux_dac32.c | 116 +++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 drivers/dac/Kconfig.mcux create mode 100644 drivers/dac/dac_mcux_dac32.c diff --git a/drivers/dac/CMakeLists.txt b/drivers/dac/CMakeLists.txt index d0c0d83e4b5..24fa9a4cb83 100644 --- a/drivers/dac/CMakeLists.txt +++ b/drivers/dac/CMakeLists.txt @@ -2,5 +2,6 @@ zephyr_library() +zephyr_library_sources_ifdef(CONFIG_DAC_MCUX_DAC32 dac_mcux_dac32.c) zephyr_library_sources_ifdef(CONFIG_DAC_STM32 dac_stm32.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE dac_handlers.c) diff --git a/drivers/dac/Kconfig b/drivers/dac/Kconfig index b824552b307..8f17692c494 100644 --- a/drivers/dac/Kconfig +++ b/drivers/dac/Kconfig @@ -17,6 +17,8 @@ module = DAC module-str = DAC source "subsys/logging/Kconfig.template.log_config" +source "drivers/dac/Kconfig.mcux" + source "drivers/dac/Kconfig.stm32" endif # DAC diff --git a/drivers/dac/Kconfig.mcux b/drivers/dac/Kconfig.mcux new file mode 100644 index 00000000000..5a4bc2c2350 --- /dev/null +++ b/drivers/dac/Kconfig.mcux @@ -0,0 +1,11 @@ +# DAC configuration options + +# Copyright (c) 2020 Henrik Brix Andersen +# +# SPDX-License-Identifier: Apache-2.0 + +config DAC_MCUX_DAC32 + bool "NXP Kinetis MCUX DAC32 driver" + depends on HAS_MCUX_DAC32 + help + Enable the driver for the NXP Kinetis MCUX DAC32. diff --git a/drivers/dac/dac_mcux_dac32.c b/drivers/dac/dac_mcux_dac32.c new file mode 100644 index 00000000000..217758c2d95 --- /dev/null +++ b/drivers/dac/dac_mcux_dac32.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_kinetis_dac32 + +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(dac_mcux_dac32, CONFIG_DAC_LOG_LEVEL); + +struct mcux_dac32_config { + DAC_Type *base; + dac32_reference_voltage_source_t reference; + bool buffered; + bool low_power; +}; + +struct mcux_dac32_data { + bool configured; +}; + +static int mcux_dac32_channel_setup(struct device *dev, + const struct dac_channel_cfg *channel_cfg) +{ + const struct mcux_dac32_config *config = dev->config->config_info; + struct mcux_dac32_data *data = dev->driver_data; + dac32_config_t dac32_config; + + if (channel_cfg->channel_id != 0) { + LOG_ERR("unsupported channel %d", channel_cfg->channel_id); + return -ENOTSUP; + } + + if (channel_cfg->resolution != 12) { + LOG_ERR("unsupported resolution %d", channel_cfg->resolution); + return -ENOTSUP; + } + + DAC32_GetDefaultConfig(&dac32_config); + dac32_config.enableLowPowerMode = config->low_power; + dac32_config.referenceVoltageSource = config->reference; + + DAC32_Init(config->base, &dac32_config); + DAC32_EnableBufferOutput(config->base, config->buffered); + + data->configured = true; + + return 0; +} + +static int mcux_dac32_write_value(struct device *dev, u8_t channel, u32_t value) +{ + const struct mcux_dac32_config *config = dev->config->config_info; + struct mcux_dac32_data *data = dev->driver_data; + + if (!data->configured) { + LOG_ERR("channel not initialized"); + return -EINVAL; + } + + if (channel != 0) { + LOG_ERR("unsupported channel %d", channel); + return -ENOTSUP; + } + + if (value >= 4096) { + LOG_ERR("value %d out of range", value); + return -EINVAL; + } + + /* Static operation */ + DAC32_EnableBuffer(config->base, false); + + DAC32_SetBufferValue(config->base, 0, value); + DAC32_Enable(config->base, true); + + return 0; +} + +static int mcux_dac32_init(struct device *dev) +{ + return 0; +} + +static const struct dac_driver_api mcux_dac32_driver_api = { + .channel_setup = mcux_dac32_channel_setup, + .write_value = mcux_dac32_write_value, +}; + +#define TO_DAC32_VREF_SRC(val) \ + _DO_CONCAT(kDAC32_ReferenceVoltageSourceVref, val) + +#define MCUX_DAC32_INIT(n) \ + static struct mcux_dac32_data mcux_dac32_data_##n; \ + \ + static const struct mcux_dac32_config mcux_dac32_config_##n = { \ + .base = (DAC_Type *)DT_INST_REG_ADDR(n), \ + .reference = \ + TO_DAC32_VREF_SRC(DT_INST_PROP(n, voltage_reference)), \ + .buffered = DT_INST_PROP(n, buffered), \ + .low_power = DT_INST_PROP(n, low_power_mode), \ + }; \ + \ + DEVICE_AND_API_INIT(mcux_dac32_##n, DT_INST_LABEL(n), \ + mcux_dac32_init, &mcux_dac32_data_##n, \ + &mcux_dac32_config_##n, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,\ + &mcux_dac32_driver_api) + +DT_INST_FOREACH(MCUX_DAC32_INIT)