Zephyr Project API 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
449
454typedef int (*dac_api_channel_setup)(const struct device *dev,
455 const struct dac_channel_cfg *channel_cfg);
456
461typedef int (*dac_api_write_value)(const struct device *dev,
462 uint8_t channel, uint32_t value);
463
473
475
489__syscall int dac_channel_setup(const struct device *dev,
490 const struct dac_channel_cfg *channel_cfg);
491
492static inline int z_impl_dac_channel_setup(const struct device *dev,
493 const struct dac_channel_cfg *channel_cfg)
494{
495 return DEVICE_API_GET(dac, dev)->channel_setup(dev, channel_cfg);
496}
497
507static inline int dac_channel_setup_dt(const struct dac_dt_spec *spec)
508{
509 if (!spec->channel_cfg_dt_node_exists) {
510 return -ENOTSUP;
511 }
512
513 return dac_channel_setup(spec->dev, &spec->channel_cfg);
514}
515
526__syscall int dac_write_value(const struct device *dev, uint8_t channel,
527 uint32_t value);
528
529static inline int z_impl_dac_write_value(const struct device *dev,
530 uint8_t channel, uint32_t value)
531{
532 return DEVICE_API_GET(dac, dev)->write_value(dev, channel, value);
533}
534
545static inline int dac_write_value_dt(const struct dac_dt_spec *spec,
546 uint32_t value)
547{
548 if (!spec->channel_cfg_dt_node_exists) {
549 return -ENOTSUP;
550 }
551
552 return dac_write_value(spec->dev, spec->channel_id, value);
553}
554
573typedef int (*dac_x_to_raw_fn)(uint32_t ref_mv, uint8_t resolution, uint32_t *valp);
574
580static inline int dac_millivolts_to_raw(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
581{
582 uint64_t dac_mv = (((uint64_t)*valp) << resolution) / (uint64_t)ref_mv;
583
584 if (dac_mv > (1UL << resolution)) {
585 __ASSERT_MSG_INFO("conversion result is out of range");
586 return -ERANGE;
587 }
588
589 *valp = (uint32_t)dac_mv;
590
591 return 0;
592}
593
599static inline int dac_microvolts_to_raw(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
600{
601 uint64_t dac_uv = (((uint64_t)*valp) << resolution) / (uint64_t)ref_mv / (uint64_t)1000;
602
603 if (dac_uv > (1UL << resolution)) {
604 __ASSERT_MSG_INFO("conversion result is out of range");
605 return -ERANGE;
606 }
607
608 *valp = (uint32_t)dac_uv;
609
610 return 0;
611}
612
626static inline int dac_x_to_raw_dt_chan(dac_x_to_raw_fn conv_func,
627 const struct dac_dt_spec *spec,
628 uint32_t *valp)
629{
630 if (!spec->channel_cfg_dt_node_exists) {
631 return -ENOTSUP;
632 }
633
634 return conv_func(spec->vref_mv, spec->channel_cfg.resolution, valp);
635}
636
650static inline int dac_millivolts_to_raw_dt(const struct dac_dt_spec *spec, uint32_t *valp)
651{
653}
654
668static inline int dac_microvolts_to_raw_dt(const struct dac_dt_spec *spec, uint32_t *valp)
669{
671}
672
680static inline bool dac_is_ready_dt(const struct dac_dt_spec *spec)
681{
682 return spec->channel_cfg_dt_node_exists && device_is_ready(spec->dev);
683}
684
688
689#ifdef __cplusplus
690}
691#endif
692
693#include <zephyr/syscalls/dac.h>
694
695#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:1425
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:573
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:626
int(* dac_api_channel_setup)(const struct device *dev, const struct dac_channel_cfg *channel_cfg)
@def_driverbackendgroup{DAC,dac_interface}
Definition dac.h:454
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:545
static bool dac_is_ready_dt(const struct dac_dt_spec *spec)
Validate that the DAC device is ready.
Definition dac.h:680
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:580
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:650
int(* dac_api_write_value)(const struct device *dev, uint8_t channel, uint32_t value)
Type definition of DAC API function for setting a write request.
Definition dac.h:461
static int dac_microvolts_to_raw(uint32_t ref_mv, uint8_t resolution, uint32_t *valp)
Convert a microvolts value to a raw DAC value.
Definition dac.h:599
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:668
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:507
bool device_is_ready(const struct device *dev)
Verify that a device is ready for use.
#define ENOTSUP
Unsupported value.
Definition errno.h:115
#define ERANGE
Result too large.
Definition errno.h:73
__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
@driver_ops{DAC}
Definition dac.h:467
dac_api_write_value write_value
@driver_ops_mandatory Write a single value to a DAC channel.
Definition dac.h:471
dac_api_channel_setup channel_setup
@driver_ops_mandatory Configure a DAC channel.
Definition dac.h:469
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