Zephyr API Documentation 4.4.0-rc1
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
dac.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Libre Solar Technologies GmbH
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
12
13#ifndef ZEPHYR_INCLUDE_DRIVERS_DAC_H_
14#define ZEPHYR_INCLUDE_DRIVERS_DAC_H_
15
16#include <zephyr/device.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
35
40#define DAC_CHANNEL_BROADCAST 0xFF
41
54 bool buffered: 1;
59 bool internal: 1;
60};
61
113#define DAC_CHANNEL_CFG_DT(node_id) { \
114 .resolution = DT_PROP_OR(node_id, zephyr_resolution, 0), \
115 .buffered = DT_PROP(node_id, zephyr_buffered), \
116 .internal = DT_PROP(node_id, zephyr_internal), \
117 .channel_id = DT_REG_ADDR(node_id), \
118}
119
158
160
161#define DAC_DT_SPEC_STRUCT(ctlr, output) { \
162 .dev = DEVICE_DT_GET(ctlr), \
163 .channel_id = output, \
164 DAC_CHANNEL_CFG_FROM_DT_NODE(\
165 DAC_CHANNEL_DT_NODE(ctlr, output)) \
166 }
167
168#define DAC_CHANNEL_DT_NODE(ctlr, output) \
169 DT_CHILD_BY_UNIT_ADDR_INT(ctlr, output)
170
171#define DAC_CHANNEL_CFG_FROM_DT_NODE(node_id) \
172 IF_ENABLED(DT_NODE_EXISTS(node_id), \
173 (.channel_cfg_dt_node_exists = true, \
174 .channel_cfg = DAC_CHANNEL_CFG_DT(node_id), \
175 .vref_mv = DT_PROP_OR(node_id, zephyr_vref_mv, 0),))
176
178
237#define DAC_DT_SPEC_GET_BY_NAME(node_id, name) \
238 DAC_DT_SPEC_STRUCT(DT_IO_CHANNELS_CTLR_BY_NAME(node_id, name), \
239 DT_IO_CHANNELS_OUTPUT_BY_NAME(node_id, name))
240
253#define DAC_DT_SPEC_GET_BY_NAME_OR(node_id, name, default_value) \
254 COND_CODE_1(DT_PROP_HAS_NAME(node_id, io_channels, name), \
255 (DAC_DT_SPEC_GET_BY_NAME(node_id, name)), (default_value))
256
267#define DAC_DT_SPEC_INST_GET_BY_NAME(inst, name) \
268 DAC_DT_SPEC_GET_BY_NAME(DT_DRV_INST(inst), name)
269
270
283#define DAC_DT_SPEC_INST_GET_BY_NAME_OR(inst, name, default_value) \
284 DAC_DT_SPEC_GET_BY_NAME_OR(DT_DRV_INST(inst), name, default_value)
285
346#define DAC_DT_SPEC_GET_BY_IDX(node_id, idx) \
347 DAC_DT_SPEC_STRUCT(DT_IO_CHANNELS_CTLR_BY_IDX(node_id, idx), \
348 COND_CODE_1(DT_PHA_HAS_CELL_AT_IDX(node_id, io_channels, idx, output), \
349 (DT_IO_CHANNELS_OUTPUT_BY_IDX(node_id, idx)), \
350 (0)))
351
364#define DAC_DT_SPEC_GET_BY_IDX_OR(node_id, idx, default_value) \
365 COND_CODE_1(DT_PROP_HAS_IDX(node_id, io_channels, idx), \
366 (DAC_DT_SPEC_GET_BY_IDX(node_id, idx)), (default_value))
367
378#define DAC_DT_SPEC_INST_GET_BY_IDX(inst, idx) \
379 DAC_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx)
380
393#define DAC_DT_SPEC_INST_GET_BY_IDX_OR(inst, idx, default_value) \
394 DAC_DT_SPEC_GET_BY_IDX_OR(DT_DRV_INST(inst), idx, default_value)
395
405#define DAC_DT_SPEC_GET(node_id) DAC_DT_SPEC_GET_BY_IDX(node_id, 0)
406
418#define DAC_DT_SPEC_GET_OR(node_id, default_value) \
419 DAC_DT_SPEC_GET_BY_IDX_OR(node_id, 0, default_value)
420
429#define DAC_DT_SPEC_INST_GET(inst) DAC_DT_SPEC_GET(DT_DRV_INST(inst))
430
442#define DAC_DT_SPEC_INST_GET_OR(inst, default_value) \
443 DAC_DT_SPEC_GET_OR(DT_DRV_INST(inst), default_value)
444
450
451/*
452 * Type definition of DAC API function for configuring a channel.
453 * See dac_channel_setup() for argument descriptions.
454 */
455typedef int (*dac_api_channel_setup)(const struct device *dev,
456 const struct dac_channel_cfg *channel_cfg);
457
458/*
459 * Type definition of DAC API function for setting a write request.
460 * See dac_write_value() for argument descriptions.
461 */
462typedef int (*dac_api_write_value)(const struct device *dev,
463 uint8_t channel, uint32_t value);
464
465/*
466 * DAC driver API
467 *
468 * This is the mandatory API any DAC driver needs to expose.
469 */
470__subsystem struct dac_driver_api {
471 dac_api_channel_setup channel_setup;
472 dac_api_write_value write_value;
473};
474
478
492__syscall int dac_channel_setup(const struct device *dev,
493 const struct dac_channel_cfg *channel_cfg);
494
495static inline int z_impl_dac_channel_setup(const struct device *dev,
496 const struct dac_channel_cfg *channel_cfg)
497{
498 const struct dac_driver_api *api =
499 (const struct dac_driver_api *)dev->api;
500
501 return api->channel_setup(dev, channel_cfg);
502}
503
513static inline int dac_channel_setup_dt(const struct dac_dt_spec *spec)
514{
515 if (!spec->channel_cfg_dt_node_exists) {
516 return -ENOTSUP;
517 }
518
519 return dac_channel_setup(spec->dev, &spec->channel_cfg);
520}
521
532__syscall int dac_write_value(const struct device *dev, uint8_t channel,
533 uint32_t value);
534
535static inline int z_impl_dac_write_value(const struct device *dev,
536 uint8_t channel, uint32_t value)
537{
538 const struct dac_driver_api *api =
539 (const struct dac_driver_api *)dev->api;
540
541 return api->write_value(dev, channel, value);
542}
543
554static inline int dac_write_value_dt(const struct dac_dt_spec *spec,
555 uint32_t value)
556{
557 if (!spec->channel_cfg_dt_node_exists) {
558 return -ENOTSUP;
559 }
560
561 return dac_write_value(spec->dev, spec->channel_id, value);
562}
563
582typedef int (*dac_x_to_raw_fn)(uint32_t ref_mv, uint8_t resolution, uint32_t *valp);
583
589static inline int dac_millivolts_to_raw(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
590{
591 uint64_t dac_mv = (((uint64_t)*valp) << resolution) / (uint64_t)ref_mv;
592
593 if (dac_mv > (1UL << resolution)) {
594 __ASSERT_MSG_INFO("conversion result is out of range");
595 return -ERANGE;
596 }
597
598 *valp = (uint32_t)dac_mv;
599
600 return 0;
601}
602
608static inline int dac_microvolts_to_raw(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
609{
610 uint64_t dac_uv = (((uint64_t)*valp) << resolution) / (uint64_t)ref_mv / (uint64_t)1000;
611
612 if (dac_uv > (1UL << resolution)) {
613 __ASSERT_MSG_INFO("conversion result is out of range");
614 return -ERANGE;
615 }
616
617 *valp = (uint32_t)dac_uv;
618
619 return 0;
620}
621
635static inline int dac_x_to_raw_dt_chan(dac_x_to_raw_fn conv_func,
636 const struct dac_dt_spec *spec,
637 uint32_t *valp)
638{
639 if (!spec->channel_cfg_dt_node_exists) {
640 return -ENOTSUP;
641 }
642
643 return conv_func(spec->vref_mv, spec->channel_cfg.resolution, valp);
644}
645
659static inline int dac_millivolts_to_raw_dt(const struct dac_dt_spec *spec, uint32_t *valp)
660{
662}
663
677static inline int dac_microvolts_to_raw_dt(const struct dac_dt_spec *spec, uint32_t *valp)
678{
680}
681
689static inline bool dac_is_ready_dt(const struct dac_dt_spec *spec)
690{
691 return spec->channel_cfg_dt_node_exists && device_is_ready(spec->dev);
692}
693
697
698#ifdef __cplusplus
699}
700#endif
701
702#include <zephyr/syscalls/dac.h>
703
704#endif /* ZEPHYR_INCLUDE_DRIVERS_DAC_H_ */
int(* dac_x_to_raw_fn)(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
Conversion from specified input units to raw DAC units.
Definition dac.h:582
int dac_write_value(const struct device *dev, uint8_t channel, uint32_t value)
Write a single value to a DAC channel.
static int dac_x_to_raw_dt_chan(dac_x_to_raw_fn conv_func, const struct dac_dt_spec *spec, uint32_t *valp)
Convert a raw DAC value to an arbitrary output unit.
Definition dac.h:635
static int dac_write_value_dt(const struct dac_dt_spec *spec, uint32_t value)
Write a single value to a DAC channel from a struct dac_dt_spec.
Definition dac.h:554
static bool dac_is_ready_dt(const struct dac_dt_spec *spec)
Validate that the DAC device is ready.
Definition dac.h:689
static int dac_millivolts_to_raw(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
Convert a millivolts value to a raw DAC value.
Definition dac.h:589
int dac_channel_setup(const struct device *dev, const struct dac_channel_cfg *channel_cfg)
Configure a DAC channel.
static int dac_millivolts_to_raw_dt(const struct dac_dt_spec *spec, uint32_t *valp)
Convert a millivolts value to raw DAC using information stored in a struct dac_dt_spec.
Definition dac.h:659
static int dac_microvolts_to_raw(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
Convert a raw DAC value to microvolts.
Definition dac.h:608
static int dac_microvolts_to_raw_dt(const struct dac_dt_spec *spec, uint32_t *valp)
Convert a microvolts value to raw DAC value using information stored in a struct dac_dt_spec.
Definition dac.h:677
static int dac_channel_setup_dt(const struct dac_dt_spec *spec)
Configure an DAC channel from a struct dac_dt_spec.
Definition dac.h:513
bool device_is_ready(const struct device *dev)
Verify that a device is ready for use.
#define ENOTSUP
Unsupported value.
Definition errno.h:114
#define ERANGE
Result too large.
Definition errno.h:72
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT64_TYPE__ uint64_t
Definition stdint.h:91
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
Structure for specifying the configuration of a DAC channel.
Definition dac.h:45
bool buffered
Enable output buffer for this channel.
Definition dac.h:54
uint8_t channel_id
Channel identifier of the DAC that should be configured.
Definition dac.h:47
uint8_t resolution
Desired resolution of the DAC (depends on device capabilities).
Definition dac.h:49
Container for DAC channel information specified in devicetree.
Definition dac.h:126
bool channel_cfg_dt_node_exists
Flag indicating whether configuration of the associated DAC channel is provided as a child node of th...
Definition dac.h:141
struct dac_channel_cfg channel_cfg
Configuration of the associated DAC channel specified in devicetree.
Definition dac.h:148
uint8_t channel_id
DAC channel identifier used by this io-channel.
Definition dac.h:134
const struct device * dev
Pointer to the device structure for the DAC driver instance used by this io-channel.
Definition dac.h:131
uint16_t vref_mv
Voltage of the reference selected for the channel or 0 if this value is not provided in devicetree.
Definition dac.h:156
Runtime device structure (in ROM) per driver instance.
Definition device.h:513
const void * api
Address of the API structure exposed by the device instance.
Definition device.h:519