Skip to content

Commit

Permalink
drivers: dac: make output buffer for STM32 DAC configurable
Browse files Browse the repository at this point in the history
If an operational amplifier is used on the DAC output it is
preferrable to disable the DAC output buffer.

Signed-off-by: Benedikt Schmidt <[email protected]>
  • Loading branch information
benediktibk committed May 16, 2023
1 parent 9ff23ed commit 73c07d3
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 23 deletions.
6 changes: 6 additions & 0 deletions doc/releases/release-notes-3.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
========================

Expand Down
55 changes: 32 additions & 23 deletions drivers/dac/dac_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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) ||
Expand All @@ -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]);
Expand Down Expand Up @@ -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)
4 changes: 4 additions & 0 deletions include/zephyr/drivers/dac.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/**
Expand Down

0 comments on commit 73c07d3

Please sign in to comment.