Zephyr API Documentation 4.4.99
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 return DEVICE_API_GET(dac, dev)->channel_setup(dev, channel_cfg);
499}
500
510static inline int dac_channel_setup_dt(const struct dac_dt_spec *spec)
511{
512 if (!spec->channel_cfg_dt_node_exists) {
513 return -ENOTSUP;
514 }
515
516 return dac_channel_setup(spec->dev, &spec->channel_cfg);
517}
518
529__syscall int dac_write_value(const struct device *dev, uint8_t channel,
530 uint32_t value);
531
532static inline int z_impl_dac_write_value(const struct device *dev,
533 uint8_t channel, uint32_t value)
534{
535 return DEVICE_API_GET(dac, dev)->write_value(dev, channel, value);
536}
537
548static inline int dac_write_value_dt(const struct dac_dt_spec *spec,
549 uint32_t value)
550{
551 if (!spec->channel_cfg_dt_node_exists) {
552 return -ENOTSUP;
553 }
554
555 return dac_write_value(spec->dev, spec->channel_id, value);
556}
557
576typedef int (*dac_x_to_raw_fn)(uint32_t ref_mv, uint8_t resolution, uint32_t *valp);
577
583static inline int dac_millivolts_to_raw(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
584{
585 uint64_t dac_mv = (((uint64_t)*valp) << resolution) / (uint64_t)ref_mv;
586
587 if (dac_mv > (1UL << resolution)) {
588 __ASSERT_MSG_INFO("conversion result is out of range");
589 return -ERANGE;
590 }
591
592 *valp = (uint32_t)dac_mv;
593
594 return 0;
595}
596
602static inline int dac_microvolts_to_raw(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
603{
604 uint64_t dac_uv = (((uint64_t)*valp) << resolution) / (uint64_t)ref_mv / (uint64_t)1000;
605
606 if (dac_uv > (1UL << resolution)) {
607 __ASSERT_MSG_INFO("conversion result is out of range");
608 return -ERANGE;
609 }
610
611 *valp = (uint32_t)dac_uv;
612
613 return 0;
614}
615
629static inline int dac_x_to_raw_dt_chan(dac_x_to_raw_fn conv_func,
630 const struct dac_dt_spec *spec,
631 uint32_t *valp)
632{
633 if (!spec->channel_cfg_dt_node_exists) {
634 return -ENOTSUP;
635 }
636
637 return conv_func(spec->vref_mv, spec->channel_cfg.resolution, valp);
638}
639
653static inline int dac_millivolts_to_raw_dt(const struct dac_dt_spec *spec, uint32_t *valp)
654{
656}
657
671static inline int dac_microvolts_to_raw_dt(const struct dac_dt_spec *spec, uint32_t *valp)
672{
674}
675
683static inline bool dac_is_ready_dt(const struct dac_dt_spec *spec)
684{
685 return spec->channel_cfg_dt_node_exists && device_is_ready(spec->dev);
686}
687
691
692#ifdef __cplusplus
693}
694#endif
695
696#include <zephyr/syscalls/dac.h>
697
698#endif /* ZEPHYR_INCLUDE_DRIVERS_DAC_H_ */
#define DEVICE_API_GET(_class, _dev)
Expands to the pointer of a device's API for a given class.
Definition device.h:1375
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:576
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:629
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:548
static bool dac_is_ready_dt(const struct dac_dt_spec *spec)
Validate that the DAC device is ready.
Definition dac.h:683
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:583
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:653
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:602
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:671
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:510
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