OwnTech DAC driver Zephyr Module is in charge of STM32 G4 DAC peripheral.
Driver capabilities
The DAC driver module allows you to control DACs on the STM32 G4 board. Currently, only DAC 1, DAC 2 and DAC 3 are supported.
The following functions are provided by the DAC driver module:
void dac_set_const_value(const struct device* dev, uint8_t channel, uint32_t value)
void dac_set_function(const struct device* dev, uint8_t channel, const dac_function_config_t* function_config)
void dac_function_update_reset(const struct device* dev, uint8_t channel, uint32_t reset_data)
void dac_function_update_step(const struct device* dev, uint8_t channel, uint32_t step_data)
void dac_pin_configure(const struct device* dev, uint8_t channel, const dac_pin_config_t* pin_config)
void dac_start(const struct device* dev, uint8_t channel)
void dac_stop(const struct device* dev, uint8_t channel)
How to use
Getting access to the driver
To use the DAC driver module, you have to include "dac.h"
in your source file:
Zephyr uses pointers to structures to interact with drivers. The required pointer can be obtained using the following functions:
const struct device* dac1 = device_get_binding(DAC1_LABEL);
const struct device* dac2 = device_get_binding(DAC2_LABEL);
const struct device* dac3 = device_get_binding(DAC3_LABEL);
Using one of these pointers, the user is able to interact with the driver functions of the specific peripheral. The pointer must be provided as first argument of all driver-related functions.
dac_set_const_value()
This function is used to configure a DAC as a constant generator. It just takes as an argument the channel on which the value has to be generated and the value to generate:
Note that after setting the initial value, the channel must be started using dac_start()
. To change the value during the course of your program, this function can be called without having to stop the channel.
dac_set_function(), dac_function_update_reset() and dac_function_update_step()
void dac_set_function(const struct device* dev, uint8_t channel, const dac_function_config_t* function_config)
void dac_function_update_reset(const struct device* dev, uint8_t channel, uint32_t reset_data)
void dac_function_update_step(const struct device* dev, uint8_t channel, uint32_t step_data)
These functions are used to configure a generator function of the DAC. dac_set_function()
provides the initial configuration of the function, while dac_function_update_reset()
and dac_function_update_step()
allow to change the values of the function.
Notes:
dac_set_function()
must be called called before starting the channel withdac_start()
, while the other two must only be called to change the values while the function is running.- Calling the value-changing functions if
dac_set_function()
has not been called will result in call being ignored. - For now, the
dac_set_function()
function is tightly linked to the STM32 LL macros, and requires includingstm32_ll_dac.h
.
The dac_set_function()
function takes a structure parameter, defined as follows:
typedef struct
{
dac_function_t dac_function;
uint32_t trigger_source;
uint32_t step_trigger_source;
uint32_t polarity;
uint32_t reset_data;
uint32_t step_data;
} dac_function_config_t;
Allowed values are:
dac_function
:dac_function_noise
,dac_function_triangle
ordac_function_sawtooth
. NOTE: Only Sawtooth function is implemented for now.trigger_source
andstep_trigger_source
: eitherLL_DAC_TRIG_SOFTWARE
or any macro with prefixLL_DAC_TRIG_EXT_
defined instm32_ll_dac.h
polarity
:LL_DAC_SAWTOOTH_POLARITY_DECREMENT
orLL_DAC_SAWTOOTH_POLARITY_INCREMENT
.reset_data
: integer between0x000
and0xFFF
.step_data
: 12.4 bit format between0x000.0
and0xFFF.F
(without the.
).
For more information about these values, please refer to RM0440, sections 22.4.2 and 22.4.9 to 22.4.11.
Example
#include <stm32_ll_dac.h>
#include "dac.h"
void configure_dac_sawtooth()
{
const struct device* dac1 = device_get_binding(DAC1_LABEL);
dac_function_config_t function_config =
{
.dac_function = dac_function_sawtooth,
.trigger_source = LL_DAC_TRIG_EXT_HRTIM_RST_TRG1,
.step_trigger_source = LL_DAC_TRIG_EXT_HRTIM_STEP_TRG1,
.polarity = LL_DAC_SAWTOOTH_POLARITY_DECREMENT,
.reset_data = 4000,
.step_data = 200
};
dac_set_function(dac1, 1, &function_config);
}
dac_pin_configure()
This function is used to set the pin configuration of the DAC output. It must be called before starting the channel with dac_start()
. For now, this function is tightly linked to the STM32 LL macros, and requires including stm32_ll_dac.h
.
The functions takes a structure parameter, defined as follows:
Allowed values are:
pin_connect
:LL_DAC_OUTPUT_CONNECT_GPIO
orLL_DAC_OUTPUT_CONNECT_INTERNAL
.pin_buffer_enable
:LL_DAC_OUTPUT_BUFFER_ENABLE
orLL_DAC_OUTPUT_BUFFER_DISABLE
.
For more information about these values, please refer to RM0440, section 22.4.2.
Example
#include <stm32_ll_dac.h>
#include "dac.h"
void configure_dac_pin()
{
const struct device* dac2 = device_get_binding(DAC2_LABEL);
dac_pin_config_t pin_config =
{
.pin_connect = LL_DAC_OUTPUT_CONNECT_GPIO,
.pin_buffer_enable = LL_DAC_OUTPUT_BUFFER_ENABLE
};
dac_pin_configure(dac2, 1, &pin_config);
}
dac_start() and dac_stop()
void dac_start(const struct device* dev, uint8_t channel)
void dac_stop(const struct device* dev, uint8_t channel)
These function are used to start and stop a channel.
A channel can be started after its initial configuration has been made, using either dac_set_const_value()
or dac_set_function()
, and if required dac_pin_configure()
.
Full configuration example
#include <stm32_ll_dac.h>
#include "dac.h"
void configure_dac1()
{
const struct device* dac1 = device_get_binding(DAC1_LABEL);
dac_function_config_t function_config =
{
.dac_function = dac_function_sawtooth,
.trigger_source = LL_DAC_TRIG_EXT_HRTIM_RST_TRG1,
.step_trigger_source = LL_DAC_TRIG_EXT_HRTIM_STEP_TRG1,
.polarity = LL_DAC_SAWTOOTH_POLARITY_DECREMENT,
.reset_data = 4000,
.step_data = 200
};
dac_pin_config_t pin_config =
{
.pin_connect = LL_DAC_OUTPUT_CONNECT_INTERNAL,
.pin_buffer_enable = LL_DAC_OUTPUT_BUFFER_DISABLE
};
dac_set_function(dac1, 1, &function_config);
dac_pin_configure(dac1, 1, &pin_config);
dac_start(dac1, 1);
}
Technical information
While Zephyr provides a DAC driver, it does not provide advanced function support, only constant value set. This driver is intended at supporting STM32G4 DAC functions, such as Sawtooth generation. In order to avoid conflict with Zephyr DAC driver, the configuration option CONFIG_DAC
must not be set to y
in prj.conf
.
This driver has a Zephyr-style implementation. It does use the standard DEVICE_DT_DEFINE()
macro that allows it to be loaded automatically if the module is enabled and the device is activated in the device tree. It also provides a board-agnostic layer that would allow, if wanted, to write DAC drivers for other boards.
The only difference with a Zephyr driver would be that it explicitly and individually checks for the presence and status of dac1
, dac2
and dac3
nodes in the device tree instead of being fully generic and run as many drivers as there are compatible nodes.
Limitations
While enums are provided for sawtooth
, noise
and triangle
functions, only sawtooth
is supported by this driver at the time.
Moreover, configuring the Sawtooth function or pin state requires including stm32_ll_dac.h
for now, as the driver directly uses macros defined in this file. It will be made more generic in a future release.
Enabling or disabling the module
This module is loaded by default. The user explicitly has to set CONFIG_OWNTECH_DAC_DRIVER=n
in prj.conf
to prevent the module from loading.