diff --git a/doc/releases/release-notes-3.4.rst b/doc/releases/release-notes-3.4.rst index 2b612cc13826899..dc0e03ae5b962b0 100644 --- a/doc/releases/release-notes-3.4.rst +++ b/doc/releases/release-notes-3.4.rst @@ -194,6 +194,12 @@ Stable API changes in this release if CS is GPIO-based or not, must now use :c:func:`spi_cs_is_gpio` or :c:func:`spi_cs_is_gpio_dt` calls. +* Added a new flag :c:struct:`dac_channel_cfg` ``buffered`` for DAC channels in + :c:struct:`dac_channel_cfg` to allow the configuration of the output buffer. + The actual interpretation of this depends on the hardware and is so far only + implemented for the STM32 DAC driver. Implicitly for this driver this changes + the default from being buffered to unbuffered. + New APIs in this release ======================== diff --git a/drivers/dac/dac_stm32.c b/drivers/dac/dac_stm32.c index a1e21a21c04963a..76c92df358de9cf 100644 --- a/drivers/dac/dac_stm32.c +++ b/drivers/dac/dac_stm32.c @@ -48,6 +48,8 @@ struct dac_stm32_cfg { struct stm32_pclken pclken; /* pinctrl configurations. */ const struct pinctrl_dev_config *pcfg; + /* disable output buffer */ + bool output_buffer_disable; }; /* Runtime driver data */ @@ -84,6 +86,7 @@ static int dac_stm32_channel_setup(const struct device *dev, { struct dac_stm32_data *data = dev->data; const struct dac_stm32_cfg *cfg = dev->config; + uint32_t output_buffer; if ((channel_cfg->channel_id - STM32_FIRST_CHANNEL >= data->channel_count) || @@ -100,10 +103,15 @@ static int dac_stm32_channel_setup(const struct device *dev, return -ENOTSUP; } - /* enable output buffer by default */ + if (channel_cfg->buffered) { + output_buffer = LL_DAC_OUTPUT_BUFFER_ENABLE; + } else { + output_buffer = LL_DAC_OUTPUT_BUFFER_DISABLE; + } + LL_DAC_SetOutputBuffer(cfg->base, table_channels[channel_cfg->channel_id - STM32_FIRST_CHANNEL], - LL_DAC_OUTPUT_BUFFER_ENABLE); + output_buffer); LL_DAC_Enable(cfg->base, table_channels[channel_cfg->channel_id - STM32_FIRST_CHANNEL]); @@ -147,27 +155,28 @@ static const struct dac_driver_api api_stm32_driver_api = { }; -#define STM32_DAC_INIT(index) \ - \ -PINCTRL_DT_INST_DEFINE(index); \ - \ -static const struct dac_stm32_cfg dac_stm32_cfg_##index = { \ - .base = (DAC_TypeDef *)DT_INST_REG_ADDR(index), \ - .pclken = { \ - .enr = DT_INST_CLOCKS_CELL(index, bits), \ - .bus = DT_INST_CLOCKS_CELL(index, bus), \ - }, \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ -}; \ - \ -static struct dac_stm32_data dac_stm32_data_##index = { \ - .channel_count = STM32_CHANNEL_COUNT \ -}; \ - \ -DEVICE_DT_INST_DEFINE(index, &dac_stm32_init, NULL, \ - &dac_stm32_data_##index, \ - &dac_stm32_cfg_##index, POST_KERNEL, \ - CONFIG_DAC_INIT_PRIORITY, \ +#define STM32_DAC_INIT(index) \ + \ +PINCTRL_DT_INST_DEFINE(index); \ + \ +static const struct dac_stm32_cfg dac_stm32_cfg_##index = { \ + .base = (DAC_TypeDef *)DT_INST_REG_ADDR(index), \ + .pclken = { \ + .enr = DT_INST_CLOCKS_CELL(index, bits), \ + .bus = DT_INST_CLOCKS_CELL(index, bus), \ + }, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .output_buffer_disable = DT_INST_PROP(index, output_buffer_disable), \ +}; \ + \ +static struct dac_stm32_data dac_stm32_data_##index = { \ + .channel_count = STM32_CHANNEL_COUNT \ +}; \ + \ +DEVICE_DT_INST_DEFINE(index, &dac_stm32_init, NULL, \ + &dac_stm32_data_##index, \ + &dac_stm32_cfg_##index, POST_KERNEL, \ + CONFIG_DAC_INIT_PRIORITY, \ &api_stm32_driver_api); DT_INST_FOREACH_STATUS_OKAY(STM32_DAC_INIT) diff --git a/include/zephyr/drivers/dac.h b/include/zephyr/drivers/dac.h index bb545f918537a66..dbc0e709593c616 100644 --- a/include/zephyr/drivers/dac.h +++ b/include/zephyr/drivers/dac.h @@ -32,10 +32,14 @@ extern "C" { * @param channel_id Channel identifier of the DAC that should be configured. * @param resolution Desired resolution of the DAC (depends on device * capabilities). + * @param buffered Enable output buffer for this channel. This is relevant for instance + * if the output is directly connected to the load, without an amplifier + * in between. The actual details on this are hardware dependent. */ struct dac_channel_cfg { uint8_t channel_id; uint8_t resolution; + bool buffered; }; /**